aboutsummaryrefslogtreecommitdiff
path: root/dep/mysqllite/mysys
diff options
context:
space:
mode:
Diffstat (limited to 'dep/mysqllite/mysys')
-rw-r--r--dep/mysqllite/mysys/ChangeLog221
-rw-r--r--dep/mysqllite/mysys/array.c383
-rw-r--r--dep/mysqllite/mysys/base64.c311
-rw-r--r--dep/mysqllite/mysys/charset-def.c354
-rw-r--r--dep/mysqllite/mysys/charset.c937
-rw-r--r--dep/mysqllite/mysys/checksum.c35
-rw-r--r--dep/mysqllite/mysys/default.c1217
-rw-r--r--dep/mysqllite/mysys/errors.c119
-rw-r--r--dep/mysqllite/mysys/hash.c769
-rw-r--r--dep/mysqllite/mysys/lf_alloc-pin.c527
-rw-r--r--dep/mysqllite/mysys/lf_dynarray.c207
-rw-r--r--dep/mysqllite/mysys/lf_hash.c503
-rw-r--r--dep/mysqllite/mysys/list.c114
-rw-r--r--dep/mysqllite/mysys/md5.c325
-rw-r--r--dep/mysqllite/mysys/mf_arr_appstr.c61
-rw-r--r--dep/mysqllite/mysys/mf_cache.c121
-rw-r--r--dep/mysqllite/mysys/mf_dirname.c154
-rw-r--r--dep/mysqllite/mysys/mf_fn_ext.c54
-rw-r--r--dep/mysqllite/mysys/mf_format.c142
-rw-r--r--dep/mysqllite/mysys/mf_getdate.c81
-rw-r--r--dep/mysqllite/mysys/mf_iocache.c1949
-rw-r--r--dep/mysqllite/mysys/mf_iocache2.c472
-rw-r--r--dep/mysqllite/mysys/mf_keycache.c4523
-rw-r--r--dep/mysqllite/mysys/mf_keycaches.c361
-rw-r--r--dep/mysqllite/mysys/mf_loadpath.c55
-rw-r--r--dep/mysqllite/mysys/mf_pack.c460
-rw-r--r--dep/mysqllite/mysys/mf_path.c120
-rw-r--r--dep/mysqllite/mysys/mf_qsort.c216
-rw-r--r--dep/mysqllite/mysys/mf_qsort2.c19
-rw-r--r--dep/mysqllite/mysys/mf_radix.c54
-rw-r--r--dep/mysqllite/mysys/mf_same.c40
-rw-r--r--dep/mysqllite/mysys/mf_sort.c41
-rw-r--r--dep/mysqllite/mysys/mf_soundex.c105
-rw-r--r--dep/mysqllite/mysys/mf_tempdir.c95
-rw-r--r--dep/mysqllite/mysys/mf_tempfile.c177
-rw-r--r--dep/mysqllite/mysys/mf_unixpath.c36
-rw-r--r--dep/mysqllite/mysys/mf_wcomp.c89
-rw-r--r--dep/mysqllite/mysys/mulalloc.c63
-rw-r--r--dep/mysqllite/mysys/my_access.c201
-rw-r--r--dep/mysqllite/mysys/my_aes.c227
-rw-r--r--dep/mysqllite/mysys/my_alarm.c32
-rw-r--r--dep/mysqllite/mysys/my_alloc.c436
-rw-r--r--dep/mysqllite/mysys/my_atomic.c67
-rw-r--r--dep/mysqllite/mysys/my_bit.c64
-rw-r--r--dep/mysqllite/mysys/my_bitmap.c932
-rw-r--r--dep/mysqllite/mysys/my_chsize.c107
-rw-r--r--dep/mysqllite/mysys/my_compress.c264
-rw-r--r--dep/mysqllite/mysys/my_conio.c222
-rw-r--r--dep/mysqllite/mysys/my_copy.c144
-rw-r--r--dep/mysqllite/mysys/my_create.c73
-rw-r--r--dep/mysqllite/mysys/my_delete.c125
-rw-r--r--dep/mysqllite/mysys/my_div.c37
-rw-r--r--dep/mysqllite/mysys/my_error.c290
-rw-r--r--dep/mysqllite/mysys/my_file.c135
-rw-r--r--dep/mysqllite/mysys/my_fopen.c358
-rw-r--r--dep/mysqllite/mysys/my_fstream.c194
-rw-r--r--dep/mysqllite/mysys/my_gethostbyname.c111
-rw-r--r--dep/mysqllite/mysys/my_gethwaddr.c226
-rw-r--r--dep/mysqllite/mysys/my_getncpus.c49
-rw-r--r--dep/mysqllite/mysys/my_getopt.c1419
-rw-r--r--dep/mysqllite/mysys/my_getpagesize.c40
-rw-r--r--dep/mysqllite/mysys/my_getsystime.c226
-rw-r--r--dep/mysqllite/mysys/my_getwd.c167
-rw-r--r--dep/mysqllite/mysys/my_handler.c604
-rw-r--r--dep/mysqllite/mysys/my_handler_errors.h71
-rw-r--r--dep/mysqllite/mysys/my_init.c607
-rw-r--r--dep/mysqllite/mysys/my_largepage.c166
-rw-r--r--dep/mysqllite/mysys/my_lib.c424
-rw-r--r--dep/mysqllite/mysys/my_libwrap.c41
-rw-r--r--dep/mysqllite/mysys/my_lock.c223
-rw-r--r--dep/mysqllite/mysys/my_lockmem.c98
-rw-r--r--dep/mysqllite/mysys/my_malloc.c162
-rw-r--r--dep/mysqllite/mysys/my_memmem.c83
-rw-r--r--dep/mysqllite/mysys/my_mess.c34
-rw-r--r--dep/mysqllite/mysys/my_mkdir.c42
-rw-r--r--dep/mysqllite/mysys/my_mmap.c88
-rw-r--r--dep/mysqllite/mysys/my_new.cc58
-rw-r--r--dep/mysqllite/mysys/my_once.c119
-rw-r--r--dep/mysqllite/mysys/my_open.c192
-rw-r--r--dep/mysqllite/mysys/my_port.c40
-rw-r--r--dep/mysqllite/mysys/my_pread.c206
-rw-r--r--dep/mysqllite/mysys/my_pthread.c469
-rw-r--r--dep/mysqllite/mysys/my_quick.c81
-rw-r--r--dep/mysqllite/mysys/my_rdtsc.c962
-rw-r--r--dep/mysqllite/mysys/my_read.c97
-rw-r--r--dep/mysqllite/mysys/my_redel.c124
-rw-r--r--dep/mysqllite/mysys/my_rename.c79
-rw-r--r--dep/mysqllite/mysys/my_seek.c102
-rw-r--r--dep/mysqllite/mysys/my_sleep.c35
-rw-r--r--dep/mysqllite/mysys/my_static.c135
-rw-r--r--dep/mysqllite/mysys/my_static.h50
-rw-r--r--dep/mysqllite/mysys/my_symlink.c167
-rw-r--r--dep/mysqllite/mysys/my_symlink2.c183
-rw-r--r--dep/mysqllite/mysys/my_sync.c175
-rw-r--r--dep/mysqllite/mysys/my_thr_init.c533
-rw-r--r--dep/mysqllite/mysys/my_wincond.c369
-rw-r--r--dep/mysqllite/mysys/my_windac.c223
-rw-r--r--dep/mysqllite/mysys/my_winerr.c123
-rw-r--r--dep/mysqllite/mysys/my_winfile.c681
-rw-r--r--dep/mysqllite/mysys/my_winthread.c192
-rw-r--r--dep/mysqllite/mysys/my_write.c100
-rw-r--r--dep/mysqllite/mysys/mysys_priv.h107
-rw-r--r--dep/mysqllite/mysys/ptr_cmp.c223
-rw-r--r--dep/mysqllite/mysys/queues.c687
-rw-r--r--dep/mysqllite/mysys/rijndael.c1379
-rw-r--r--dep/mysqllite/mysys/sha1.c422
-rw-r--r--dep/mysqllite/mysys/stacktrace.c714
-rw-r--r--dep/mysqllite/mysys/string.c182
-rw-r--r--dep/mysqllite/mysys/thr_alarm.c972
-rw-r--r--dep/mysqllite/mysys/thr_lock.c1688
-rw-r--r--dep/mysqllite/mysys/thr_mutex.c503
-rw-r--r--dep/mysqllite/mysys/thr_rwlock.c472
-rw-r--r--dep/mysqllite/mysys/tree.c757
-rw-r--r--dep/mysqllite/mysys/typelib.c388
114 files changed, 0 insertions, 38288 deletions
diff --git a/dep/mysqllite/mysys/ChangeLog b/dep/mysqllite/mysys/ChangeLog
deleted file mode 100644
index 7a426106667..00000000000
--- a/dep/mysqllite/mysys/ChangeLog
+++ /dev/null
@@ -1,221 +0,0 @@
-2000-02-16 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added an extra argument to the compare routine for queues to allow
- more advanced key compare functions.
-
-2000-02-10 Michael Widenius <monty@monty.pp.sci.fi>
-
-* Added THR_READ_NO_INSERT lock privilege to thr_lock.
-
-1999-08-21 Michael Widenius <monty@tik.pp.sci.fi>
-
-* Fix that '-1.49 or -1.49' is true
-* Allow negative hexadecimal numbers (like -0x0f).
-* Fixed problem with auto_increment on float and double.
-
-Wed Dec 17 02:13:58 1997 <monty@monty.pp.sci.fi>
-
-* Faster flush of keycache.
-
-Sat Dec 2 21:36:20 1995 Michael Widenius (monty@bitch)
-
- * array.c push_element & alloc_element.
-
-Wed Mar 3 00:54:20 1993 Michael Widenius (monty@bitch)
-
- * Removed automatic O_TRUNC from my_create.
-
-Wed Oct 28 02:10:56 1992 Michael Widenius (monty@bitch)
-
- * Enabled ASNYNC_IO on SUN.
-
-Mon Aug 31 23:51:13 1992 Michael Widenius (monty@bitch)
-
- * Changed tree_insert to return element if ok.
- * Added new define tree_set_pointer().
- * Chagned delete_queue() to not free if allready freed.
-
-Mon Aug 17 01:46:36 1992 Michael Widenius (monty@bitch)
-
- * Added ny cashing-rutine mf_iocash for quicker io.
-
-Wed Aug 12 13:41:18 1992 Michael Widenius (monty@bitch)
-
- * Added new function get_copy_of_memory for combined malloc/copy.
- * Splitted my_malloc to three files.
-
-Thu Jan 23 22:02:37 1992 Michael Widenius (monty at LYNX)
-
- * Added range-checks and aligned checks on ptrs to
- safe_malloc:free and safe_malloc:realloc to catch more
- error nicely without core-dumps.
-
-Wed Nov 13 01:52:18 1991 Michael Widenius (monty at LYNX)
-
- * Added use of mysys as a shared library.
-
-Sat Nov 9 14:38:21 1991 Michael Widenius (monty at LYNX)
-
- * Added expand of ~username to unpack_dirname.
-
-Tue Sep 17 21:15:08 1991 Michael Widenius (monty at LYNX)
-
- * Don't free null-pointers if passed to my_free
-
-Fri May 17 20:11:27 1991 Michael Widenius (monty at LYNX)
-
- * Changed all char * to string. (Can't change const char * because
- of bug in C-definition.
-
-Tue Apr 30 01:32:56 1991 Michael Widenius (monty at LYNX)
-
- * my_path now examines environment for posix variable "_" if
- progname is given and has no path.
-
-Mon Apr 22 16:12:56 1991 Michael Widenius (monty at LYNX)
-
- * Added function my_load_path() to fix path to a hard-path.
-
-Mon Apr 15 22:08:58 1991 Michael Widenius (monty at LYNX)
-
- * Added more info on DBUG-stream when freeing unallocated data.
-
-Wed Apr 3 18:41:28 1991 Michael Widenius (monty at LYNX)
-
- * Added global flag sf_malloc_no_sanity to make it possibly
- to avoid sanity-checks in right code with uses malloc a lot.
-
-Tue Mar 26 15:09:45 1991 Mikael WIDENIUS (monty at panther)
-
- * Made soundex look nicer
-
-Sat Mar 23 10:49:49 1991 Michael Widenius (monty at LYNX)
-
- * Added init of alarm variables to skip some warnings from gcc.
-
-Tue Mar 5 16:50:34 1991 Michael Widenius (monty at LYNX)
-
- * Our qsort now only test if compare() function returns >= 0
- and is optimized for compare() returning > 0.
-
-Fri Nov 23 23:53:46 1990 Michael Widenius (monty at LYNX)
-
- * Added function my_set_alarm_variable to get a variable set
- on some time.
- my_alarm.h added for functions who want to print stat after
- a given time or after a number of loops.
- Changed my_lock to use new function and use defines in my_alarm.h
-
-Mon Oct 1 13:16:15 1990 Michael Widenius (monty at LYNX)
-
- * Added use of asynchronic io in read_cash_record().
- * Added write_cash and flush_write_cash to record cashing.
-
-Sun Sep 16 22:05:25 1990 Michael Widenius (monty at LYNX)
-
- * Added optional alarm to my_lock if one has FCNTL_LOCK. Added new
- defines to my_sys.h.
-
-Mon Aug 27 22:20:38 1990 Michael Widenius (monty at lynx)
-
- * my_end() now can print output about executed program.
- * Added parameter-defines for my_end in my_sys.h
-
-Sun Apr 1 23:29:47 1990 Monty (monty at monty)
-
- * Changed mf_keydisk.c to have separate functions for read and write.
- Read can now return pointer to intern key-buffer to skip
- unessessary memcpy-s.
-
-Fri Mar 23 23:03:39 1990 Monty (monty at monty)
-
- * function test_if_hard_pathname() added in dirname.c
- * my_getwd now only saves changed current dir if dir is a
- hard pathname.
- * changed my_path() to use test_if_hard_pathname()
-
-Thu Mar 1 14:47:59 1990 Monty (monty at monty)
-
- * New function my_path().
-
-Sat Feb 24 02:54:35 1990 Monty (monty at monty)
-
- * Added print of my_progname in my_mess.c
-
-Sun Feb 11 17:55:58 1990 David Axmark (davida at isil)
-
- * Concatenated libarys my_func and my_sys because of to much
- crosswise dependencies.
- * Fixed varagrs code in mf_fixadr.c
-
-Mon Dec 4 17:36:16 1989 Monty (monty at monty)
-
- * Changed safemalloc() to use my_message() if out of memory and
- to check MY_WME if we want this error-messages.
- * Changed my_setwd() to use dos_setdrive() insted of system().
-
-Wed Oct 25 02:56:07 1989 Monty (monty at monty)
-
- * Changed my_mktmp1() to work like tempnam() with default dirname.
- * Changed name of my_mktmp1.c to my_tempnam.c
-
-Thu Oct 19 16:39:27 1989 David Axmark (davida at isil)
-
- * Removed libary mysysnc. Instead added a hook to my_error that
- can call my_message if needed.
-
-Thu Oct 5 01:33:29 1989 David Axmark (davida at isil)
-
- * Use MY_SEEK_{SET,CUR,END} as arguments to my_seek
-
- * Added a a array of structs that holds properties of open files.
- Removed include file extras.h
-
-Wed Jun 21 01:34:04 1989 Monty (monty at monty)
-
- * Added two new malloc-functions: my_once_alloc() and
- my_once_free(). These give easyer and quicker startup.
-
-Mon May 22 14:03:44 1989 Monty (monty at monty)
-
- * Fixed my_getwd and my_setwd so they work.
- * Added extern variabel curr_char[] with is set to current
- directory after my_getwd() or my_setwd();
-
-Mon Jan 23 03:38:50 1989 Monty (monty at monty)
-
- * Changed my_chsize to check if NO_CHSIZE is defined. If new file
- should be shorter it fills unused part with null.
- * Changed my_lock to not check for arg 0 (Functions should use
- LK_TO_EOF to lock all file.
-
-Tue Dec 6 15:09:44 1988 Monty (monty at monty)
-
- * Added DBUG_PRINT if error in my_seek.
-
-Mon Dec 5 15:58:48 1988 Monty (monty at monty)
-
- * Added DBUG_PRINT if not all byte read/written in my_read(),
- my_fread(), my_write() and my_fwrite();
-
-Sat Dec 3 01:48:03 1988 Monty (monty at monty)
-
- * Fixed bug in Makefile; quick did't work.
- * Changed safemalloc to use bmove, bfill and memcpy when handling
- memoryblocks.
-
-Fri Dec 2 03:29:21 1988 Monty (monty at monty)
-
- * Added more defines under MEMORY in my_func.h
- * Added functions to llib-lmysys.
- * Removed RCS/* files and installed ewerything as stable.
- (Because errors in old RCS-files.
-
-Wed Nov 9 00:32:33 1988 Monty (monty at monty)
-
- * Changed realloc for MSDOS; Previous version freed old block on
- * error, new version (of compiler) dosn't.
-
-Wed Oct 26 21:07:27 1988 Monty (monty at monty)
-
- * Fixed missing updateing of my_stream_opened;
diff --git a/dep/mysqllite/mysys/array.c b/dep/mysqllite/mysys/array.c
deleted file mode 100644
index 70c7a59aa3a..00000000000
--- a/dep/mysqllite/mysys/array.c
+++ /dev/null
@@ -1,383 +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 */
-
-/* Handling of arrays that can grow dynamicly. */
-
-#include "mysys_priv.h"
-#include "m_string.h"
-
-/*
- Initiate dynamic array
-
- SYNOPSIS
- init_dynamic_array2()
- array Pointer to an array
- element_size Size of element
- init_buffer Initial buffer pointer
- init_alloc Number of initial elements
- alloc_increment Increment for adding new elements
-
- DESCRIPTION
- init_dynamic_array() initiates array and allocate space for
- init_alloc eilements.
- Array is usable even if space allocation failed, hence, the
- function never returns TRUE.
- Static buffers must begin immediately after the array structure.
-
- RETURN VALUE
- FALSE Ok
-*/
-
-my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size,
- void *init_buffer, uint init_alloc,
- uint alloc_increment)
-{
- DBUG_ENTER("init_dynamic_array");
- if (!alloc_increment)
- {
- alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16);
- if (init_alloc > 8 && alloc_increment > init_alloc * 2)
- alloc_increment=init_alloc*2;
- }
-
- if (!init_alloc)
- {
- init_alloc=alloc_increment;
- init_buffer= 0;
- }
- array->elements=0;
- array->max_element=init_alloc;
- array->alloc_increment=alloc_increment;
- array->size_of_element=element_size;
- if ((array->buffer= init_buffer))
- DBUG_RETURN(FALSE);
- /*
- Since the dynamic array is usable even if allocation fails here malloc
- should not throw an error
- */
- if (!(array->buffer= (uchar*) my_malloc(element_size*init_alloc, MYF(0))))
- array->max_element=0;
- DBUG_RETURN(FALSE);
-}
-
-my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
- uint init_alloc, uint alloc_increment)
-{
- /* placeholder to preserve ABI */
- return my_init_dynamic_array_ci(array, element_size, init_alloc,
- alloc_increment);
-}
-/*
- Insert element at the end of array. Allocate memory if needed.
-
- SYNOPSIS
- insert_dynamic()
- array
- element
-
- RETURN VALUE
- TRUE Insert failed
- FALSE Ok
-*/
-
-my_bool insert_dynamic(DYNAMIC_ARRAY *array, uchar* element)
-{
- uchar* buffer;
- if (array->elements == array->max_element)
- { /* Call only when nessesary */
- if (!(buffer=alloc_dynamic(array)))
- return TRUE;
- }
- else
- {
- buffer=array->buffer+(array->elements * array->size_of_element);
- array->elements++;
- }
- memcpy(buffer,element,(size_t) array->size_of_element);
- return FALSE;
-}
-
-
-/*
- Alloc space for next element(s)
-
- SYNOPSIS
- alloc_dynamic()
- array
-
- DESCRIPTION
- alloc_dynamic() checks if there is empty space for at least
- one element if not tries to allocate space for alloc_increment
- elements at the end of array.
-
- RETURN VALUE
- pointer Pointer to empty space for element
- 0 Error
-*/
-
-uchar *alloc_dynamic(DYNAMIC_ARRAY *array)
-{
- if (array->elements == array->max_element)
- {
- char *new_ptr;
- if (array->buffer == (uchar *)(array + 1))
- {
- /*
- In this senerio, the buffer is statically preallocated,
- so we have to create an all-new malloc since we overflowed
- */
- if (!(new_ptr= (char *) my_malloc((array->max_element+
- array->alloc_increment) *
- array->size_of_element,
- MYF(MY_WME))))
- return 0;
- memcpy(new_ptr, array->buffer,
- array->elements * array->size_of_element);
- }
- else
- if (!(new_ptr=(char*) my_realloc(array->buffer,(array->max_element+
- array->alloc_increment)*
- array->size_of_element,
- MYF(MY_WME | MY_ALLOW_ZERO_PTR))))
- return 0;
- array->buffer= (uchar*) new_ptr;
- array->max_element+=array->alloc_increment;
- }
- return array->buffer+(array->elements++ * array->size_of_element);
-}
-
-
-/*
- Pop last element from array.
-
- SYNOPSIS
- pop_dynamic()
- array
-
- RETURN VALUE
- pointer Ok
- 0 Array is empty
-*/
-
-uchar *pop_dynamic(DYNAMIC_ARRAY *array)
-{
- if (array->elements)
- return array->buffer+(--array->elements * array->size_of_element);
- return 0;
-}
-
-/*
- Replace element in array with given element and index
-
- SYNOPSIS
- set_dynamic()
- array
- element Element to be inserted
- idx Index where element is to be inserted
-
- DESCRIPTION
- set_dynamic() replaces element in array.
- If idx > max_element insert new element. Allocate memory if needed.
-
- RETURN VALUE
- TRUE Idx was out of range and allocation of new memory failed
- FALSE Ok
-*/
-
-my_bool set_dynamic(DYNAMIC_ARRAY *array, uchar* element, uint idx)
-{
- if (idx >= array->elements)
- {
- if (idx >= array->max_element && allocate_dynamic(array, idx))
- return TRUE;
- bzero((uchar*) (array->buffer+array->elements*array->size_of_element),
- (idx - array->elements)*array->size_of_element);
- array->elements=idx+1;
- }
- memcpy(array->buffer+(idx * array->size_of_element),element,
- (size_t) array->size_of_element);
- return FALSE;
-}
-
-
-/*
- Ensure that dynamic array has enough elements
-
- SYNOPSIS
- allocate_dynamic()
- array
- max_elements Numbers of elements that is needed
-
- NOTES
- Any new allocated element are NOT initialized
-
- RETURN VALUE
- FALSE Ok
- TRUE Allocation of new memory failed
-*/
-
-my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements)
-{
- if (max_elements >= array->max_element)
- {
- uint size;
- uchar *new_ptr;
- size= (max_elements + array->alloc_increment)/array->alloc_increment;
- size*= array->alloc_increment;
- if (array->buffer == (uchar *)(array + 1))
- {
- /*
- In this senerio, the buffer is statically preallocated,
- so we have to create an all-new malloc since we overflowed
- */
- if (!(new_ptr= (uchar *) my_malloc(size *
- array->size_of_element,
- MYF(MY_WME))))
- return 0;
- memcpy(new_ptr, array->buffer,
- array->elements * array->size_of_element);
- }
- else
-
-
- if (!(new_ptr= (uchar*) my_realloc(array->buffer,size*
- array->size_of_element,
- MYF(MY_WME | MY_ALLOW_ZERO_PTR))))
- return TRUE;
- array->buffer= new_ptr;
- array->max_element= size;
- }
- return FALSE;
-}
-
-
-/*
- Get an element from array by given index
-
- SYNOPSIS
- get_dynamic()
- array
- uchar* Element to be returned. If idx > elements contain zeroes.
- idx Index of element wanted.
-*/
-
-void get_dynamic(DYNAMIC_ARRAY *array, uchar* element, uint idx)
-{
- if (idx >= array->elements)
- {
- DBUG_PRINT("warning",("To big array idx: %d, array size is %d",
- idx,array->elements));
- bzero(element,array->size_of_element);
- return;
- }
- memcpy(element,array->buffer+idx*array->size_of_element,
- (size_t) array->size_of_element);
-}
-
-
-/*
- Empty array by freeing all memory
-
- SYNOPSIS
- delete_dynamic()
- array Array to be deleted
-*/
-
-void delete_dynamic(DYNAMIC_ARRAY *array)
-{
- /*
- Just mark as empty if we are using a static buffer
- */
- if (array->buffer == (uchar *)(array + 1))
- array->elements= 0;
- else
- if (array->buffer)
- {
- my_free(array->buffer);
- array->buffer=0;
- array->elements=array->max_element=0;
- }
-}
-
-/*
- Delete element by given index
-
- SYNOPSIS
- delete_dynamic_element()
- array
- idx Index of element to be deleted
-*/
-
-void delete_dynamic_element(DYNAMIC_ARRAY *array, uint idx)
-{
- char *ptr= (char*) array->buffer+array->size_of_element*idx;
- array->elements--;
- memmove(ptr,ptr+array->size_of_element,
- (array->elements-idx)*array->size_of_element);
-}
-
-
-/*
- Free unused memory
-
- SYNOPSIS
- freeze_size()
- array Array to be freed
-
-*/
-
-void freeze_size(DYNAMIC_ARRAY *array)
-{
- uint elements=max(array->elements,1);
-
- /*
- Do nothing if we are using a static buffer
- */
- if (array->buffer == (uchar *)(array + 1))
- return;
-
- if (array->buffer && array->max_element != elements)
- {
- array->buffer=(uchar*) my_realloc(array->buffer,
- elements*array->size_of_element,
- MYF(MY_WME));
- 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, uchar* element)
-{
- size_t 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/dep/mysqllite/mysys/base64.c b/dep/mysqllite/mysys/base64.c
deleted file mode 100644
index ab66715c929..00000000000
--- a/dep/mysqllite/mysys/base64.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/* Copyright (C) 2003 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> /* strchr() */
-#include <m_ctype.h> /* my_isspace() */
-#include <base64.h>
-
-#ifndef MAIN
-
-static char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz"
- "0123456789+/";
-
-
-int
-base64_needed_encoded_length(int length_of_data)
-{
- int nb_base64_chars;
- nb_base64_chars= (length_of_data + 2) / 3 * 4;
-
- return
- nb_base64_chars + /* base64 char incl padding */
- (nb_base64_chars - 1)/ 76 + /* newlines */
- 1; /* NUL termination of string */
-}
-
-
-int
-base64_needed_decoded_length(int length_of_encoded_data)
-{
- return (int) ceil(length_of_encoded_data * 3 / 4);
-}
-
-
-/*
- Encode a data as base64.
-
- Note: We require that dst is pre-allocated to correct size.
- See base64_needed_encoded_length().
-*/
-
-int
-base64_encode(const void *src, size_t src_len, char *dst)
-{
- const unsigned char *s= (const unsigned char*)src;
- size_t i= 0;
- size_t len= 0;
-
- for (; i < src_len; len += 4)
- {
- unsigned c;
-
- if (len == 76)
- {
- len= 0;
- *dst++= '\n';
- }
-
- c= s[i++];
- c <<= 8;
-
- if (i < src_len)
- c += s[i];
- c <<= 8;
- i++;
-
- if (i < src_len)
- c += s[i];
- i++;
-
- *dst++= base64_table[(c >> 18) & 0x3f];
- *dst++= base64_table[(c >> 12) & 0x3f];
-
- if (i > (src_len + 1))
- *dst++= '=';
- else
- *dst++= base64_table[(c >> 6) & 0x3f];
-
- if (i > src_len)
- *dst++= '=';
- else
- *dst++= base64_table[(c >> 0) & 0x3f];
- }
- *dst= '\0';
-
- return 0;
-}
-
-
-static inline uint
-pos(unsigned char c)
-{
- return (uint) (strchr(base64_table, c) - base64_table);
-}
-
-
-#define SKIP_SPACE(src, i, size) \
-{ \
- while (i < size && my_isspace(&my_charset_latin1, * src)) \
- { \
- i++; \
- src++; \
- } \
- if (i == size) \
- { \
- break; \
- } \
-}
-
-
-/*
- Decode a base64 string
-
- 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.
-
- 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_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 < len)
- {
- unsigned c= 0;
- size_t mark= 0;
-
- SKIP_SPACE(src, i, len);
-
- c += pos(*src++);
- c <<= 6;
- i++;
-
- SKIP_SPACE(src, i, len);
-
- c += pos(*src++);
- c <<= 6;
- i++;
-
- SKIP_SPACE(src, i, len);
-
- if (*src != '=')
- c += pos(*src++);
- else
- {
- src += 2; /* There should be two bytes padding */
- i= len;
- mark= 2;
- c <<= 6;
- goto end;
- }
- c <<= 6;
- i++;
-
- SKIP_SPACE(src, i, len);
-
- if (*src != '=')
- c += pos(*src++);
- else
- {
- src += 1; /* There should be one byte padding */
- i= len;
- mark= 1;
- goto end;
- }
- i++;
-
- end:
- b[0]= (c >> 16) & 0xff;
- b[1]= (c >> 8) & 0xff;
- b[2]= (c >> 0) & 0xff;
-
- for (j=0; j<3-mark; j++)
- *d++= b[j];
- }
-
- 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 : (int) (d - dst_base);
-}
-
-
-#else /* MAIN */
-
-#define require(b) { \
- if (!(b)) { \
- printf("Require failed at %s:%d\n", __FILE__, __LINE__); \
- abort(); \
- } \
-}
-
-
-int
-main(void)
-{
- int i;
- size_t j;
- size_t k, l;
- size_t dst_len;
- size_t needed_length;
-
- for (i= 0; i < 500; i++)
- {
- /* Create source data */
- const size_t src_len= rand() % 1000 + 1;
-
- char * src= (char *) malloc(src_len);
- char * s= src;
- char * str;
- char * dst;
-
- require(src);
- for (j= 0; j<src_len; j++)
- {
- char c= rand();
- *s++= c;
- }
-
- /* Encode */
- needed_length= base64_needed_encoded_length(src_len);
- str= (char *) malloc(needed_length);
- require(str);
- for (k= 0; k < needed_length; k++)
- str[k]= 0xff; /* Fill memory to check correct NUL termination */
- require(base64_encode(src, src_len, str) == 0);
- require(needed_length == strlen(str) + 1);
-
- /* Decode */
- dst= (char *) malloc(base64_needed_decoded_length(strlen(str)));
- require(dst);
- dst_len= base64_decode(str, strlen(str), dst, NULL);
- require(dst_len == src_len);
-
- if (memcmp(src, dst, src_len) != 0)
- {
- printf(" --------- src --------- --------- dst ---------\n");
- for (k= 0; k<src_len; k+=8)
- {
- printf("%.4x ", (uint) k);
- for (l=0; l<8 && k+l<src_len; l++)
- {
- unsigned char c= src[k+l];
- printf("%.2x ", (unsigned)c);
- }
-
- printf(" ");
-
- for (l=0; l<8 && k+l<dst_len; l++)
- {
- unsigned char c= dst[k+l];
- printf("%.2x ", (unsigned)c);
- }
- printf("\n");
- }
- printf("src length: %.8x, dst length: %.8x\n",
- (uint) src_len, (uint) dst_len);
- require(0);
- }
- }
- printf("Test succeeded.\n");
- return 0;
-}
-
-#endif
diff --git a/dep/mysqllite/mysys/charset-def.c b/dep/mysqllite/mysys/charset-def.c
deleted file mode 100644
index 9089347f002..00000000000
--- a/dep/mysqllite/mysys/charset-def.c
+++ /dev/null
@@ -1,354 +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 all compiled character sets into the client
- If a client don't want to use all of them, he can define his own
- init_compiled_charsets() that only adds those that he wants
-*/
-
-#ifdef HAVE_UCA_COLLATIONS
-
-#ifdef HAVE_CHARSET_ucs2
-extern CHARSET_INFO my_charset_ucs2_icelandic_uca_ci;
-extern CHARSET_INFO my_charset_ucs2_latvian_uca_ci;
-extern CHARSET_INFO my_charset_ucs2_romanian_uca_ci;
-extern CHARSET_INFO my_charset_ucs2_slovenian_uca_ci;
-extern CHARSET_INFO my_charset_ucs2_polish_uca_ci;
-extern CHARSET_INFO my_charset_ucs2_estonian_uca_ci;
-extern CHARSET_INFO my_charset_ucs2_spanish_uca_ci;
-extern CHARSET_INFO my_charset_ucs2_swedish_uca_ci;
-extern CHARSET_INFO my_charset_ucs2_turkish_uca_ci;
-extern CHARSET_INFO my_charset_ucs2_czech_uca_ci;
-extern CHARSET_INFO my_charset_ucs2_danish_uca_ci;
-extern CHARSET_INFO my_charset_ucs2_lithuanian_uca_ci;
-extern CHARSET_INFO my_charset_ucs2_slovak_uca_ci;
-extern CHARSET_INFO my_charset_ucs2_spanish2_uca_ci;
-extern CHARSET_INFO my_charset_ucs2_roman_uca_ci;
-extern CHARSET_INFO my_charset_ucs2_persian_uca_ci;
-extern CHARSET_INFO my_charset_ucs2_esperanto_uca_ci;
-extern CHARSET_INFO my_charset_ucs2_hungarian_uca_ci;
-extern CHARSET_INFO my_charset_ucs2_sinhala_uca_ci;
-#endif
-
-
-#ifdef HAVE_CHARSET_utf32
-extern CHARSET_INFO my_charset_utf32_icelandic_uca_ci;
-extern CHARSET_INFO my_charset_utf32_latvian_uca_ci;
-extern CHARSET_INFO my_charset_utf32_romanian_uca_ci;
-extern CHARSET_INFO my_charset_utf32_slovenian_uca_ci;
-extern CHARSET_INFO my_charset_utf32_polish_uca_ci;
-extern CHARSET_INFO my_charset_utf32_estonian_uca_ci;
-extern CHARSET_INFO my_charset_utf32_spanish_uca_ci;
-extern CHARSET_INFO my_charset_utf32_swedish_uca_ci;
-extern CHARSET_INFO my_charset_utf32_turkish_uca_ci;
-extern CHARSET_INFO my_charset_utf32_czech_uca_ci;
-extern CHARSET_INFO my_charset_utf32_danish_uca_ci;
-extern CHARSET_INFO my_charset_utf32_lithuanian_uca_ci;
-extern CHARSET_INFO my_charset_utf32_slovak_uca_ci;
-extern CHARSET_INFO my_charset_utf32_spanish2_uca_ci;
-extern CHARSET_INFO my_charset_utf32_roman_uca_ci;
-extern CHARSET_INFO my_charset_utf32_persian_uca_ci;
-extern CHARSET_INFO my_charset_utf32_esperanto_uca_ci;
-extern CHARSET_INFO my_charset_utf32_hungarian_uca_ci;
-extern CHARSET_INFO my_charset_utf32_sinhala_uca_ci;
-#endif /* HAVE_CHARSET_utf32 */
-
-
-#ifdef HAVE_CHARSET_utf16
-extern CHARSET_INFO my_charset_utf16_icelandic_uca_ci;
-extern CHARSET_INFO my_charset_utf16_latvian_uca_ci;
-extern CHARSET_INFO my_charset_utf16_romanian_uca_ci;
-extern CHARSET_INFO my_charset_utf16_slovenian_uca_ci;
-extern CHARSET_INFO my_charset_utf16_polish_uca_ci;
-extern CHARSET_INFO my_charset_utf16_estonian_uca_ci;
-extern CHARSET_INFO my_charset_utf16_spanish_uca_ci;
-extern CHARSET_INFO my_charset_utf16_swedish_uca_ci;
-extern CHARSET_INFO my_charset_utf16_turkish_uca_ci;
-extern CHARSET_INFO my_charset_utf16_czech_uca_ci;
-extern CHARSET_INFO my_charset_utf16_danish_uca_ci;
-extern CHARSET_INFO my_charset_utf16_lithuanian_uca_ci;
-extern CHARSET_INFO my_charset_utf16_slovak_uca_ci;
-extern CHARSET_INFO my_charset_utf16_spanish2_uca_ci;
-extern CHARSET_INFO my_charset_utf16_roman_uca_ci;
-extern CHARSET_INFO my_charset_utf16_persian_uca_ci;
-extern CHARSET_INFO my_charset_utf16_esperanto_uca_ci;
-extern CHARSET_INFO my_charset_utf16_hungarian_uca_ci;
-extern CHARSET_INFO my_charset_utf16_sinhala_uca_ci;
-#endif /* HAVE_CHARSET_utf16 */
-
-
-#ifdef HAVE_CHARSET_utf8
-extern CHARSET_INFO my_charset_utf8_icelandic_uca_ci;
-extern CHARSET_INFO my_charset_utf8_latvian_uca_ci;
-extern CHARSET_INFO my_charset_utf8_romanian_uca_ci;
-extern CHARSET_INFO my_charset_utf8_slovenian_uca_ci;
-extern CHARSET_INFO my_charset_utf8_polish_uca_ci;
-extern CHARSET_INFO my_charset_utf8_estonian_uca_ci;
-extern CHARSET_INFO my_charset_utf8_spanish_uca_ci;
-extern CHARSET_INFO my_charset_utf8_swedish_uca_ci;
-extern CHARSET_INFO my_charset_utf8_turkish_uca_ci;
-extern CHARSET_INFO my_charset_utf8_czech_uca_ci;
-extern CHARSET_INFO my_charset_utf8_danish_uca_ci;
-extern CHARSET_INFO my_charset_utf8_lithuanian_uca_ci;
-extern CHARSET_INFO my_charset_utf8_slovak_uca_ci;
-extern CHARSET_INFO my_charset_utf8_spanish2_uca_ci;
-extern CHARSET_INFO my_charset_utf8_roman_uca_ci;
-extern CHARSET_INFO my_charset_utf8_persian_uca_ci;
-extern CHARSET_INFO my_charset_utf8_esperanto_uca_ci;
-extern CHARSET_INFO my_charset_utf8_hungarian_uca_ci;
-extern CHARSET_INFO my_charset_utf8_sinhala_uca_ci;
-#ifdef HAVE_UTF8_GENERAL_CS
-extern CHARSET_INFO my_charset_utf8_general_cs;
-#endif
-#endif
-
-#ifdef HAVE_CHARSET_utf8mb4
-extern CHARSET_INFO my_charset_utf8mb4_icelandic_uca_ci;
-extern CHARSET_INFO my_charset_utf8mb4_latvian_uca_ci;
-extern CHARSET_INFO my_charset_utf8mb4_romanian_uca_ci;
-extern CHARSET_INFO my_charset_utf8mb4_slovenian_uca_ci;
-extern CHARSET_INFO my_charset_utf8mb4_polish_uca_ci;
-extern CHARSET_INFO my_charset_utf8mb4_estonian_uca_ci;
-extern CHARSET_INFO my_charset_utf8mb4_spanish_uca_ci;
-extern CHARSET_INFO my_charset_utf8mb4_swedish_uca_ci;
-extern CHARSET_INFO my_charset_utf8mb4_turkish_uca_ci;
-extern CHARSET_INFO my_charset_utf8mb4_czech_uca_ci;
-extern CHARSET_INFO my_charset_utf8mb4_danish_uca_ci;
-extern CHARSET_INFO my_charset_utf8mb4_lithuanian_uca_ci;
-extern CHARSET_INFO my_charset_utf8mb4_slovak_uca_ci;
-extern CHARSET_INFO my_charset_utf8mb4_spanish2_uca_ci;
-extern CHARSET_INFO my_charset_utf8mb4_roman_uca_ci;
-extern CHARSET_INFO my_charset_utf8mb4_persian_uca_ci;
-extern CHARSET_INFO my_charset_utf8mb4_esperanto_uca_ci;
-extern CHARSET_INFO my_charset_utf8mb4_hungarian_uca_ci;
-extern CHARSET_INFO my_charset_utf8mb4_sinhala_uca_ci;
-#endif /* HAVE_CHARSET_utf8mb4 */
-
-#endif /* HAVE_UCA_COLLATIONS */
-
-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);
- add_compiled_collation(&my_charset_latin1_german2_ci);
-
-#ifdef HAVE_CHARSET_big5
- add_compiled_collation(&my_charset_big5_chinese_ci);
- add_compiled_collation(&my_charset_big5_bin);
-#endif
-
-#ifdef HAVE_CHARSET_cp1250
- add_compiled_collation(&my_charset_cp1250_czech_ci);
-#endif
-
-#ifdef HAVE_CHARSET_cp932
- add_compiled_collation(&my_charset_cp932_japanese_ci);
- add_compiled_collation(&my_charset_cp932_bin);
-#endif
-
-#ifdef HAVE_CHARSET_latin2
- add_compiled_collation(&my_charset_latin2_czech_ci);
-#endif
-
-#ifdef HAVE_CHARSET_eucjpms
- add_compiled_collation(&my_charset_eucjpms_japanese_ci);
- add_compiled_collation(&my_charset_eucjpms_bin);
-#endif
-
-#ifdef HAVE_CHARSET_euckr
- add_compiled_collation(&my_charset_euckr_korean_ci);
- add_compiled_collation(&my_charset_euckr_bin);
-#endif
-
-#ifdef HAVE_CHARSET_gb2312
- add_compiled_collation(&my_charset_gb2312_chinese_ci);
- add_compiled_collation(&my_charset_gb2312_bin);
-#endif
-
-#ifdef HAVE_CHARSET_gbk
- add_compiled_collation(&my_charset_gbk_chinese_ci);
- add_compiled_collation(&my_charset_gbk_bin);
-#endif
-
-#ifdef HAVE_CHARSET_sjis
- add_compiled_collation(&my_charset_sjis_japanese_ci);
- add_compiled_collation(&my_charset_sjis_bin);
-#endif
-
-#ifdef HAVE_CHARSET_tis620
- add_compiled_collation(&my_charset_tis620_thai_ci);
- add_compiled_collation(&my_charset_tis620_bin);
-#endif
-
-#ifdef HAVE_CHARSET_ucs2
- add_compiled_collation(&my_charset_ucs2_general_ci);
- add_compiled_collation(&my_charset_ucs2_bin);
-#ifdef HAVE_UCA_COLLATIONS
- add_compiled_collation(&my_charset_ucs2_unicode_ci);
- add_compiled_collation(&my_charset_ucs2_icelandic_uca_ci);
- add_compiled_collation(&my_charset_ucs2_latvian_uca_ci);
- add_compiled_collation(&my_charset_ucs2_romanian_uca_ci);
- add_compiled_collation(&my_charset_ucs2_slovenian_uca_ci);
- add_compiled_collation(&my_charset_ucs2_polish_uca_ci);
- add_compiled_collation(&my_charset_ucs2_estonian_uca_ci);
- add_compiled_collation(&my_charset_ucs2_spanish_uca_ci);
- add_compiled_collation(&my_charset_ucs2_swedish_uca_ci);
- add_compiled_collation(&my_charset_ucs2_turkish_uca_ci);
- add_compiled_collation(&my_charset_ucs2_czech_uca_ci);
- add_compiled_collation(&my_charset_ucs2_danish_uca_ci);
- add_compiled_collation(&my_charset_ucs2_lithuanian_uca_ci);
- add_compiled_collation(&my_charset_ucs2_slovak_uca_ci);
- add_compiled_collation(&my_charset_ucs2_spanish2_uca_ci);
- add_compiled_collation(&my_charset_ucs2_roman_uca_ci);
- add_compiled_collation(&my_charset_ucs2_persian_uca_ci);
- add_compiled_collation(&my_charset_ucs2_esperanto_uca_ci);
- add_compiled_collation(&my_charset_ucs2_hungarian_uca_ci);
- add_compiled_collation(&my_charset_ucs2_sinhala_uca_ci);
-#endif
-#endif
-
-#ifdef HAVE_CHARSET_ujis
- add_compiled_collation(&my_charset_ujis_japanese_ci);
- add_compiled_collation(&my_charset_ujis_bin);
-#endif
-
-#ifdef HAVE_CHARSET_utf8
- add_compiled_collation(&my_charset_utf8_general_ci);
- add_compiled_collation(&my_charset_utf8_bin);
-#ifdef HAVE_UTF8_GENERAL_CS
- add_compiled_collation(&my_charset_utf8_general_cs);
-#endif
-#ifdef HAVE_UCA_COLLATIONS
- add_compiled_collation(&my_charset_utf8_unicode_ci);
- add_compiled_collation(&my_charset_utf8_icelandic_uca_ci);
- add_compiled_collation(&my_charset_utf8_latvian_uca_ci);
- add_compiled_collation(&my_charset_utf8_romanian_uca_ci);
- add_compiled_collation(&my_charset_utf8_slovenian_uca_ci);
- add_compiled_collation(&my_charset_utf8_polish_uca_ci);
- add_compiled_collation(&my_charset_utf8_estonian_uca_ci);
- add_compiled_collation(&my_charset_utf8_spanish_uca_ci);
- add_compiled_collation(&my_charset_utf8_swedish_uca_ci);
- add_compiled_collation(&my_charset_utf8_turkish_uca_ci);
- add_compiled_collation(&my_charset_utf8_czech_uca_ci);
- add_compiled_collation(&my_charset_utf8_danish_uca_ci);
- add_compiled_collation(&my_charset_utf8_lithuanian_uca_ci);
- add_compiled_collation(&my_charset_utf8_slovak_uca_ci);
- add_compiled_collation(&my_charset_utf8_spanish2_uca_ci);
- add_compiled_collation(&my_charset_utf8_roman_uca_ci);
- add_compiled_collation(&my_charset_utf8_persian_uca_ci);
- add_compiled_collation(&my_charset_utf8_esperanto_uca_ci);
- add_compiled_collation(&my_charset_utf8_hungarian_uca_ci);
- add_compiled_collation(&my_charset_utf8_sinhala_uca_ci);
-#endif
-#endif /* HAVE_CHARSET_utf8 */
-
-
-#ifdef HAVE_CHARSET_utf8mb4
- add_compiled_collation(&my_charset_utf8mb4_general_ci);
- add_compiled_collation(&my_charset_utf8mb4_bin);
-#ifdef HAVE_UCA_COLLATIONS
- add_compiled_collation(&my_charset_utf8mb4_unicode_ci);
- add_compiled_collation(&my_charset_utf8mb4_icelandic_uca_ci);
- add_compiled_collation(&my_charset_utf8mb4_latvian_uca_ci);
- add_compiled_collation(&my_charset_utf8mb4_romanian_uca_ci);
- add_compiled_collation(&my_charset_utf8mb4_slovenian_uca_ci);
- add_compiled_collation(&my_charset_utf8mb4_polish_uca_ci);
- add_compiled_collation(&my_charset_utf8mb4_estonian_uca_ci);
- add_compiled_collation(&my_charset_utf8mb4_spanish_uca_ci);
- add_compiled_collation(&my_charset_utf8mb4_swedish_uca_ci);
- add_compiled_collation(&my_charset_utf8mb4_turkish_uca_ci);
- add_compiled_collation(&my_charset_utf8mb4_czech_uca_ci);
- add_compiled_collation(&my_charset_utf8mb4_danish_uca_ci);
- add_compiled_collation(&my_charset_utf8mb4_lithuanian_uca_ci);
- add_compiled_collation(&my_charset_utf8mb4_slovak_uca_ci);
- add_compiled_collation(&my_charset_utf8mb4_spanish2_uca_ci);
- add_compiled_collation(&my_charset_utf8mb4_roman_uca_ci);
- add_compiled_collation(&my_charset_utf8mb4_persian_uca_ci);
- add_compiled_collation(&my_charset_utf8mb4_esperanto_uca_ci);
- add_compiled_collation(&my_charset_utf8mb4_hungarian_uca_ci);
- add_compiled_collation(&my_charset_utf8mb4_sinhala_uca_ci);
-#endif /* HAVE_UCA_COLLATIONS */
-#endif /* HAVE_CHARSET_utf8mb4 */
-
-
-#ifdef HAVE_CHARSET_utf16
- add_compiled_collation(&my_charset_utf16_general_ci);
- add_compiled_collation(&my_charset_utf16_bin);
-#ifdef HAVE_UCA_COLLATIONS
- add_compiled_collation(&my_charset_utf16_unicode_ci);
- add_compiled_collation(&my_charset_utf16_icelandic_uca_ci);
- add_compiled_collation(&my_charset_utf16_latvian_uca_ci);
- add_compiled_collation(&my_charset_utf16_romanian_uca_ci);
- add_compiled_collation(&my_charset_utf16_slovenian_uca_ci);
- add_compiled_collation(&my_charset_utf16_polish_uca_ci);
- add_compiled_collation(&my_charset_utf16_estonian_uca_ci);
- add_compiled_collation(&my_charset_utf16_spanish_uca_ci);
- add_compiled_collation(&my_charset_utf16_swedish_uca_ci);
- add_compiled_collation(&my_charset_utf16_turkish_uca_ci);
- add_compiled_collation(&my_charset_utf16_czech_uca_ci);
- add_compiled_collation(&my_charset_utf16_danish_uca_ci);
- add_compiled_collation(&my_charset_utf16_lithuanian_uca_ci);
- add_compiled_collation(&my_charset_utf16_slovak_uca_ci);
- add_compiled_collation(&my_charset_utf16_spanish2_uca_ci);
- add_compiled_collation(&my_charset_utf16_roman_uca_ci);
- add_compiled_collation(&my_charset_utf16_persian_uca_ci);
- add_compiled_collation(&my_charset_utf16_esperanto_uca_ci);
- add_compiled_collation(&my_charset_utf16_hungarian_uca_ci);
- add_compiled_collation(&my_charset_utf16_sinhala_uca_ci);
-#endif /* HAVE_UCA_COLLATIOINS */
-#endif /* HAVE_CHARSET_utf16 */
-
-
-#ifdef HAVE_CHARSET_utf32
- add_compiled_collation(&my_charset_utf32_general_ci);
- add_compiled_collation(&my_charset_utf32_bin);
-#ifdef HAVE_UCA_COLLATIONS
- add_compiled_collation(&my_charset_utf32_unicode_ci);
- add_compiled_collation(&my_charset_utf32_icelandic_uca_ci);
- add_compiled_collation(&my_charset_utf32_latvian_uca_ci);
- add_compiled_collation(&my_charset_utf32_romanian_uca_ci);
- add_compiled_collation(&my_charset_utf32_slovenian_uca_ci);
- add_compiled_collation(&my_charset_utf32_polish_uca_ci);
- add_compiled_collation(&my_charset_utf32_estonian_uca_ci);
- add_compiled_collation(&my_charset_utf32_spanish_uca_ci);
- add_compiled_collation(&my_charset_utf32_swedish_uca_ci);
- add_compiled_collation(&my_charset_utf32_turkish_uca_ci);
- add_compiled_collation(&my_charset_utf32_czech_uca_ci);
- add_compiled_collation(&my_charset_utf32_danish_uca_ci);
- add_compiled_collation(&my_charset_utf32_lithuanian_uca_ci);
- add_compiled_collation(&my_charset_utf32_slovak_uca_ci);
- add_compiled_collation(&my_charset_utf32_spanish2_uca_ci);
- add_compiled_collation(&my_charset_utf32_roman_uca_ci);
- add_compiled_collation(&my_charset_utf32_persian_uca_ci);
- add_compiled_collation(&my_charset_utf32_esperanto_uca_ci);
- add_compiled_collation(&my_charset_utf32_hungarian_uca_ci);
- add_compiled_collation(&my_charset_utf32_sinhala_uca_ci);
-#endif /* HAVE_UCA_COLLATIONS */
-#endif /* HAVE_CHARSET_utf32 */
-
- /* Copy compiled charsets */
- for (cs=compiled_charsets; cs->name; cs++)
- add_compiled_collation(cs);
-
- return FALSE;
-}
diff --git a/dep/mysqllite/mysys/charset.c b/dep/mysqllite/mysys/charset.c
deleted file mode 100644
index 167d6b8ff6e..00000000000
--- a/dep/mysqllite/mysys/charset.c
+++ /dev/null
@@ -1,937 +0,0 @@
-/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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"
-#include <m_ctype.h>
-#include <m_string.h>
-#include <my_dir.h>
-#include <my_xml.h>
-
-
-/*
- The code below implements this functionality:
-
- - Initializing charset related structures
- - Loading dynamic charsets
- - Searching for a proper CHARSET_INFO
- using charset name, collation name or collation ID
- - Setting server default character set
-*/
-
-my_bool my_charset_same(CHARSET_INFO *cs1, CHARSET_INFO *cs2)
-{
- return ((cs1 == cs2) || !strcmp(cs1->csname,cs2->csname));
-}
-
-
-static uint
-get_collation_number_internal(const char *name)
-{
- CHARSET_INFO **cs;
- for (cs= all_charsets;
- cs < all_charsets + array_elements(all_charsets);
- cs++)
- {
- if ( cs[0] && cs[0]->name &&
- !my_strcasecmp(&my_charset_latin1, cs[0]->name, name))
- return cs[0]->number;
- }
- return 0;
-}
-
-
-static my_bool init_state_maps(CHARSET_INFO *cs)
-{
- uint i;
- uchar *state_map;
- uchar *ident_map;
-
- if (!(cs->state_map= (uchar*) my_once_alloc(256, MYF(MY_WME))))
- return 1;
-
- if (!(cs->ident_map= (uchar*) my_once_alloc(256, MYF(MY_WME))))
- return 1;
-
- state_map= cs->state_map;
- ident_map= cs->ident_map;
-
- /* Fill state_map with states to get a faster parser */
- for (i=0; i < 256 ; i++)
- {
- if (my_isalpha(cs,i))
- state_map[i]=(uchar) MY_LEX_IDENT;
- else if (my_isdigit(cs,i))
- state_map[i]=(uchar) MY_LEX_NUMBER_IDENT;
-#if defined(USE_MB) && defined(USE_MB_IDENT)
- else if (my_mbcharlen(cs, i)>1)
- state_map[i]=(uchar) MY_LEX_IDENT;
-#endif
- else if (my_isspace(cs,i))
- state_map[i]=(uchar) MY_LEX_SKIP;
- else
- state_map[i]=(uchar) MY_LEX_CHAR;
- }
- state_map[(uchar)'_']=state_map[(uchar)'$']=(uchar) MY_LEX_IDENT;
- state_map[(uchar)'\'']=(uchar) MY_LEX_STRING;
- state_map[(uchar)'.']=(uchar) MY_LEX_REAL_OR_POINT;
- state_map[(uchar)'>']=state_map[(uchar)'=']=state_map[(uchar)'!']= (uchar) MY_LEX_CMP_OP;
- state_map[(uchar)'<']= (uchar) MY_LEX_LONG_CMP_OP;
- state_map[(uchar)'&']=state_map[(uchar)'|']=(uchar) MY_LEX_BOOL;
- state_map[(uchar)'#']=(uchar) MY_LEX_COMMENT;
- state_map[(uchar)';']=(uchar) MY_LEX_SEMICOLON;
- state_map[(uchar)':']=(uchar) MY_LEX_SET_VAR;
- state_map[0]=(uchar) MY_LEX_EOL;
- state_map[(uchar)'\\']= (uchar) MY_LEX_ESCAPE;
- state_map[(uchar)'/']= (uchar) MY_LEX_LONG_COMMENT;
- state_map[(uchar)'*']= (uchar) MY_LEX_END_LONG_COMMENT;
- state_map[(uchar)'@']= (uchar) MY_LEX_USER_END;
- state_map[(uchar) '`']= (uchar) MY_LEX_USER_VARIABLE_DELIMITER;
- state_map[(uchar)'"']= (uchar) MY_LEX_STRING_OR_DELIMITER;
-
- /*
- Create a second map to make it faster to find identifiers
- */
- for (i=0; i < 256 ; i++)
- {
- ident_map[i]= (uchar) (state_map[i] == MY_LEX_IDENT ||
- state_map[i] == MY_LEX_NUMBER_IDENT);
- }
-
- /* Special handling of hex and binary strings */
- state_map[(uchar)'x']= state_map[(uchar)'X']= (uchar) MY_LEX_IDENT_OR_HEX;
- state_map[(uchar)'b']= state_map[(uchar)'B']= (uchar) MY_LEX_IDENT_OR_BIN;
- state_map[(uchar)'n']= state_map[(uchar)'N']= (uchar) MY_LEX_IDENT_OR_NCHAR;
- return 0;
-}
-
-
-static void simple_cs_init_functions(CHARSET_INFO *cs)
-{
- if (cs->state & MY_CS_BINSORT)
- cs->coll= &my_collation_8bit_bin_handler;
- else
- cs->coll= &my_collation_8bit_simple_ci_handler;
-
- cs->cset= &my_charset_8bit_handler;
-}
-
-
-
-static int cs_copy_data(CHARSET_INFO *to, CHARSET_INFO *from)
-{
- to->number= from->number ? from->number : to->number;
-
- if (from->csname)
- if (!(to->csname= my_once_strdup(from->csname,MYF(MY_WME))))
- goto err;
-
- if (from->name)
- if (!(to->name= my_once_strdup(from->name,MYF(MY_WME))))
- goto err;
-
- if (from->comment)
- if (!(to->comment= my_once_strdup(from->comment,MYF(MY_WME))))
- goto err;
-
- if (from->ctype)
- {
- if (!(to->ctype= (uchar*) my_once_memdup((char*) from->ctype,
- MY_CS_CTYPE_TABLE_SIZE,
- MYF(MY_WME))))
- goto err;
- if (init_state_maps(to))
- goto err;
- }
- if (from->to_lower)
- if (!(to->to_lower= (uchar*) my_once_memdup((char*) from->to_lower,
- MY_CS_TO_LOWER_TABLE_SIZE,
- MYF(MY_WME))))
- goto err;
-
- if (from->to_upper)
- if (!(to->to_upper= (uchar*) my_once_memdup((char*) from->to_upper,
- MY_CS_TO_UPPER_TABLE_SIZE,
- MYF(MY_WME))))
- goto err;
- if (from->sort_order)
- {
- if (!(to->sort_order= (uchar*) my_once_memdup((char*) from->sort_order,
- MY_CS_SORT_ORDER_TABLE_SIZE,
- MYF(MY_WME))))
- goto err;
-
- }
- if (from->tab_to_uni)
- {
- uint sz= MY_CS_TO_UNI_TABLE_SIZE*sizeof(uint16);
- if (!(to->tab_to_uni= (uint16*) my_once_memdup((char*)from->tab_to_uni,
- sz, MYF(MY_WME))))
- goto err;
- }
- if (from->tailoring)
- if (!(to->tailoring= my_once_strdup(from->tailoring,MYF(MY_WME))))
- goto err;
-
- return 0;
-
-err:
- return 1;
-}
-
-
-
-static my_bool simple_cs_is_full(CHARSET_INFO *cs)
-{
- return ((cs->csname && cs->tab_to_uni && cs->ctype && cs->to_upper &&
- cs->to_lower) &&
- (cs->number && cs->name &&
- (cs->sort_order || (cs->state & MY_CS_BINSORT) )));
-}
-
-
-static void
-copy_uca_collation(CHARSET_INFO *to, CHARSET_INFO *from)
-{
- to->cset= from->cset;
- to->coll= from->coll;
- to->strxfrm_multiply= from->strxfrm_multiply;
- to->min_sort_char= from->min_sort_char;
- to->max_sort_char= from->max_sort_char;
- to->mbminlen= from->mbminlen;
- to->mbmaxlen= from->mbmaxlen;
- to->state|= MY_CS_AVAILABLE | MY_CS_LOADED |
- MY_CS_STRNXFRM | MY_CS_UNICODE;
-}
-
-
-static int add_collation(CHARSET_INFO *cs)
-{
- if (cs->name && (cs->number ||
- (cs->number=get_collation_number_internal(cs->name))) &&
- cs->number < array_elements(all_charsets))
- {
- if (!all_charsets[cs->number])
- {
- if (!(all_charsets[cs->number]=
- (CHARSET_INFO*) my_once_alloc(sizeof(CHARSET_INFO),MYF(0))))
- return MY_XML_ERROR;
- bzero((void*)all_charsets[cs->number],sizeof(CHARSET_INFO));
- }
-
- if (cs->primary_number == cs->number)
- cs->state |= MY_CS_PRIMARY;
-
- if (cs->binary_number == cs->number)
- cs->state |= MY_CS_BINSORT;
-
- all_charsets[cs->number]->state|= cs->state;
-
- if (!(all_charsets[cs->number]->state & MY_CS_COMPILED))
- {
- CHARSET_INFO *newcs= all_charsets[cs->number];
- if (cs_copy_data(all_charsets[cs->number],cs))
- return MY_XML_ERROR;
-
- newcs->caseup_multiply= newcs->casedn_multiply= 1;
-
- if (!strcmp(cs->csname,"ucs2") )
- {
-#if defined(HAVE_CHARSET_ucs2) && defined(HAVE_UCA_COLLATIONS)
- copy_uca_collation(newcs, &my_charset_ucs2_unicode_ci);
- newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED | MY_CS_NONASCII;
-#endif
- }
- else if (!strcmp(cs->csname, "utf8") || !strcmp(cs->csname, "utf8mb3"))
- {
-#if defined (HAVE_CHARSET_utf8) && defined(HAVE_UCA_COLLATIONS)
- copy_uca_collation(newcs, &my_charset_utf8_unicode_ci);
- newcs->ctype= my_charset_utf8_unicode_ci.ctype;
- if (init_state_maps(newcs))
- return MY_XML_ERROR;
-#endif
- }
- else if (!strcmp(cs->csname, "utf8mb4"))
- {
-#if defined (HAVE_CHARSET_utf8mb4) && defined(HAVE_UCA_COLLATIONS)
- copy_uca_collation(newcs, &my_charset_utf8mb4_unicode_ci);
- newcs->ctype= my_charset_utf8mb4_unicode_ci.ctype;
- newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED;
-#endif
- }
- else if (!strcmp(cs->csname, "utf16"))
- {
-#if defined (HAVE_CHARSET_utf16) && defined(HAVE_UCA_COLLATIONS)
- copy_uca_collation(newcs, &my_charset_utf16_unicode_ci);
- newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED | MY_CS_NONASCII;
-#endif
- }
- else if (!strcmp(cs->csname, "utf32"))
- {
-#if defined (HAVE_CHARSET_utf32) && defined(HAVE_UCA_COLLATIONS)
- copy_uca_collation(newcs, &my_charset_utf32_unicode_ci);
- newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED | MY_CS_NONASCII;
-#endif
- }
- else
- {
- uchar *sort_order= all_charsets[cs->number]->sort_order;
- simple_cs_init_functions(all_charsets[cs->number]);
- newcs->mbminlen= 1;
- newcs->mbmaxlen= 1;
- if (simple_cs_is_full(all_charsets[cs->number]))
- {
- all_charsets[cs->number]->state |= MY_CS_LOADED;
- }
- all_charsets[cs->number]->state|= MY_CS_AVAILABLE;
-
- /*
- Check if case sensitive sort order: A < a < B.
- We need MY_CS_FLAG for regex library, and for
- case sensitivity flag for 5.0 client protocol,
- to support isCaseSensitive() method in JDBC driver
- */
- if (sort_order && sort_order['A'] < sort_order['a'] &&
- sort_order['a'] < sort_order['B'])
- all_charsets[cs->number]->state|= MY_CS_CSSORT;
-
- if (my_charset_is_8bit_pure_ascii(all_charsets[cs->number]))
- all_charsets[cs->number]->state|= MY_CS_PUREASCII;
- if (!my_charset_is_ascii_compatible(cs))
- all_charsets[cs->number]->state|= MY_CS_NONASCII;
- }
- }
- else
- {
- /*
- We need the below to make get_charset_name()
- and get_charset_number() working even if a
- character set has not been really incompiled.
- The above functions are used for example
- in error message compiler extra/comp_err.c.
- If a character set was compiled, this information
- will get lost and overwritten in add_compiled_collation().
- */
- CHARSET_INFO *dst= all_charsets[cs->number];
- dst->number= cs->number;
- if (cs->comment)
- if (!(dst->comment= my_once_strdup(cs->comment,MYF(MY_WME))))
- return MY_XML_ERROR;
- if (cs->csname)
- if (!(dst->csname= my_once_strdup(cs->csname,MYF(MY_WME))))
- return MY_XML_ERROR;
- if (cs->name)
- if (!(dst->name= my_once_strdup(cs->name,MYF(MY_WME))))
- return MY_XML_ERROR;
- }
- cs->number= 0;
- cs->primary_number= 0;
- cs->binary_number= 0;
- cs->name= NULL;
- cs->state= 0;
- cs->sort_order= NULL;
- cs->state= 0;
- }
- return MY_XML_OK;
-}
-
-
-#define MY_MAX_ALLOWED_BUF 1024*1024
-#define MY_CHARSET_INDEX "Index.xml"
-
-const char *charsets_dir= NULL;
-
-
-static my_bool my_read_charset_file(const char *filename, myf myflags)
-{
- uchar *buf;
- int fd;
- size_t len, tmp_len;
- MY_STAT stat_info;
-
- if (!my_stat(filename, &stat_info, MYF(myflags)) ||
- ((len= (uint)stat_info.st_size) > MY_MAX_ALLOWED_BUF) ||
- !(buf= (uchar*) my_malloc(len,myflags)))
- return TRUE;
-
- if ((fd= mysql_file_open(key_file_charset, filename, O_RDONLY, myflags)) < 0)
- goto error;
- tmp_len= mysql_file_read(fd, buf, len, myflags);
- mysql_file_close(fd, myflags);
- if (tmp_len != len)
- goto error;
-
- if (my_parse_charset_xml((char*) buf,len,add_collation))
- {
-#ifdef NOT_YET
- printf("ERROR at line %d pos %d '%s'\n",
- my_xml_error_lineno(&p)+1,
- my_xml_error_pos(&p),
- my_xml_error_string(&p));
-#endif
- }
-
- my_free(buf);
- return FALSE;
-
-error:
- my_free(buf);
- return TRUE;
-}
-
-
-char *get_charsets_dir(char *buf)
-{
- const char *sharedir= SHAREDIR;
- char *res;
- DBUG_ENTER("get_charsets_dir");
-
- if (charsets_dir != NULL)
- strmake(buf, charsets_dir, FN_REFLEN-1);
- else
- {
- if (test_if_hard_path(sharedir) ||
- is_prefix(sharedir, DEFAULT_CHARSET_HOME))
- strxmov(buf, sharedir, "/", CHARSET_DIR, NullS);
- else
- strxmov(buf, DEFAULT_CHARSET_HOME, "/", sharedir, "/", CHARSET_DIR,
- NullS);
- }
- res= convert_dirname(buf,buf,NullS);
- DBUG_PRINT("info",("charsets dir: '%s'", buf));
- DBUG_RETURN(res);
-}
-
-CHARSET_INFO *all_charsets[MY_ALL_CHARSETS_SIZE]={NULL};
-CHARSET_INFO *default_charset_info = &my_charset_latin1;
-
-void add_compiled_collation(CHARSET_INFO *cs)
-{
- all_charsets[cs->number]= cs;
- cs->state|= MY_CS_AVAILABLE;
-}
-
-static void *cs_alloc(size_t size)
-{
- return my_once_alloc(size, MYF(MY_WME));
-}
-
-
-static my_pthread_once_t charsets_initialized= MY_PTHREAD_ONCE_INIT;
-static my_pthread_once_t charsets_template= MY_PTHREAD_ONCE_INIT;
-
-static void init_available_charsets(void)
-{
- char fname[FN_REFLEN + sizeof(MY_CHARSET_INDEX)];
- CHARSET_INFO **cs;
-
- bzero(&all_charsets,sizeof(all_charsets));
- init_compiled_charsets(MYF(0));
-
- /* Copy compiled charsets */
- for (cs=all_charsets;
- cs < all_charsets+array_elements(all_charsets)-1 ;
- cs++)
- {
- if (*cs)
- {
- if (cs[0]->ctype)
- if (init_state_maps(*cs))
- *cs= NULL;
- }
- }
-
- strmov(get_charsets_dir(fname), MY_CHARSET_INDEX);
- my_read_charset_file(fname, MYF(0));
-}
-
-
-void free_charsets(void)
-{
- charsets_initialized= charsets_template;
-}
-
-
-static const char*
-get_collation_name_alias(const char *name, char *buf, size_t bufsize)
-{
- if (!strncasecmp(name, "utf8mb3_", 8))
- {
- my_snprintf(buf, bufsize, "utf8_%s", name + 8);
- return buf;
- }
- return NULL;
-}
-
-
-uint get_collation_number(const char *name)
-{
- uint id;
- char alias[64];
- my_pthread_once(&charsets_initialized, init_available_charsets);
- if ((id= get_collation_number_internal(name)))
- return id;
- if ((name= get_collation_name_alias(name, alias, sizeof(alias))))
- return get_collation_number_internal(name);
- return 0;
-}
-
-
-static uint
-get_charset_number_internal(const char *charset_name, uint cs_flags)
-{
- CHARSET_INFO **cs;
-
- for (cs= all_charsets;
- cs < all_charsets + array_elements(all_charsets);
- cs++)
- {
- if ( cs[0] && cs[0]->csname && (cs[0]->state & cs_flags) &&
- !my_strcasecmp(&my_charset_latin1, cs[0]->csname, charset_name))
- return cs[0]->number;
- }
- return 0;
-}
-
-
-static const char*
-get_charset_name_alias(const char *name)
-{
- if (!my_strcasecmp(&my_charset_latin1, name, "utf8mb3"))
- return "utf8";
- return NULL;
-}
-
-
-uint get_charset_number(const char *charset_name, uint cs_flags)
-{
- uint id;
- my_pthread_once(&charsets_initialized, init_available_charsets);
- if ((id= get_charset_number_internal(charset_name, cs_flags)))
- return id;
- if ((charset_name= get_charset_name_alias(charset_name)))
- return get_charset_number_internal(charset_name, cs_flags);
- return 0;
-}
-
-
-const char *get_charset_name(uint charset_number)
-{
- CHARSET_INFO *cs;
- my_pthread_once(&charsets_initialized, init_available_charsets);
-
- cs=all_charsets[charset_number];
- if (cs && (cs->number == charset_number) && cs->name )
- return (char*) cs->name;
-
- return (char*) "?"; /* this mimics find_type() */
-}
-
-
-static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags)
-{
- char buf[FN_REFLEN];
- CHARSET_INFO *cs;
-
- if ((cs= all_charsets[cs_number]))
- {
- if (cs->state & MY_CS_READY) /* if CS is already initialized */
- return cs;
-
- /*
- To make things thread safe we are not allowing other threads to interfere
- while we may changing the cs_info_table
- */
- mysql_mutex_lock(&THR_LOCK_charset);
-
- if (!(cs->state & (MY_CS_COMPILED|MY_CS_LOADED))) /* if CS is not in memory */
- {
- strxmov(get_charsets_dir(buf), cs->csname, ".xml", NullS);
- my_read_charset_file(buf,flags);
- }
-
- if (cs->state & MY_CS_AVAILABLE)
- {
- if (!(cs->state & MY_CS_READY))
- {
- if ((cs->cset->init && cs->cset->init(cs, cs_alloc)) ||
- (cs->coll->init && cs->coll->init(cs, cs_alloc)))
- cs= NULL;
- else
- cs->state|= MY_CS_READY;
- }
- }
- else
- cs= NULL;
-
- mysql_mutex_unlock(&THR_LOCK_charset);
- }
- return cs;
-}
-
-
-CHARSET_INFO *get_charset(uint cs_number, myf flags)
-{
- CHARSET_INFO *cs;
- if (cs_number == default_charset_info->number)
- return default_charset_info;
-
- my_pthread_once(&charsets_initialized, init_available_charsets);
-
- if (!cs_number || cs_number > array_elements(all_charsets))
- return NULL;
-
- cs=get_internal_charset(cs_number, flags);
-
- if (!cs && (flags & MY_WME))
- {
- char index_file[FN_REFLEN + sizeof(MY_CHARSET_INDEX)], cs_string[23];
- strmov(get_charsets_dir(index_file),MY_CHARSET_INDEX);
- cs_string[0]='#';
- int10_to_str(cs_number, cs_string+1, 10);
- my_error(EE_UNKNOWN_CHARSET, MYF(ME_BELL), cs_string, index_file);
- }
- return cs;
-}
-
-CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags)
-{
- uint cs_number;
- CHARSET_INFO *cs;
- my_pthread_once(&charsets_initialized, init_available_charsets);
-
- cs_number=get_collation_number(cs_name);
- cs= cs_number ? get_internal_charset(cs_number,flags) : NULL;
-
- if (!cs && (flags & MY_WME))
- {
- char index_file[FN_REFLEN + sizeof(MY_CHARSET_INDEX)];
- strmov(get_charsets_dir(index_file),MY_CHARSET_INDEX);
- my_error(EE_UNKNOWN_COLLATION, MYF(ME_BELL), cs_name, index_file);
- }
-
- return cs;
-}
-
-
-CHARSET_INFO *get_charset_by_csname(const char *cs_name,
- uint cs_flags,
- myf flags)
-{
- uint cs_number;
- CHARSET_INFO *cs;
- DBUG_ENTER("get_charset_by_csname");
- DBUG_PRINT("enter",("name: '%s'", cs_name));
-
- my_pthread_once(&charsets_initialized, init_available_charsets);
-
- cs_number= get_charset_number(cs_name, cs_flags);
- cs= cs_number ? get_internal_charset(cs_number, flags) : NULL;
-
- if (!cs && (flags & MY_WME))
- {
- char index_file[FN_REFLEN + sizeof(MY_CHARSET_INDEX)];
- strmov(get_charsets_dir(index_file),MY_CHARSET_INDEX);
- my_error(EE_UNKNOWN_CHARSET, MYF(ME_BELL), cs_name, index_file);
- }
-
- DBUG_RETURN(cs);
-}
-
-
-/**
- Resolve character set by the character set name (utf8, latin1, ...).
-
- The function tries to resolve character set by the specified name. If
- there is character set with the given name, it is assigned to the "cs"
- parameter and FALSE is returned. If there is no such character set,
- "default_cs" is assigned to the "cs" and TRUE is returned.
-
- @param[in] cs_name Character set name.
- @param[in] default_cs Default character set.
- @param[out] cs Variable to store character set.
-
- @return FALSE if character set was resolved successfully; TRUE if there
- is no character set with given name.
-*/
-
-my_bool resolve_charset(const char *cs_name,
- CHARSET_INFO *default_cs,
- CHARSET_INFO **cs)
-{
- *cs= get_charset_by_csname(cs_name, MY_CS_PRIMARY, MYF(0));
-
- if (*cs == NULL)
- {
- *cs= default_cs;
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-/**
- Resolve collation by the collation name (utf8_general_ci, ...).
-
- The function tries to resolve collation by the specified name. If there
- is collation with the given name, it is assigned to the "cl" parameter
- and FALSE is returned. If there is no such collation, "default_cl" is
- assigned to the "cl" and TRUE is returned.
-
- @param[out] cl Variable to store collation.
- @param[in] cl_name Collation name.
- @param[in] default_cl Default collation.
-
- @return FALSE if collation was resolved successfully; TRUE if there is no
- collation with given name.
-*/
-
-my_bool resolve_collation(const char *cl_name,
- CHARSET_INFO *default_cl,
- CHARSET_INFO **cl)
-{
- *cl= get_charset_by_name(cl_name, MYF(0));
-
- if (*cl == NULL)
- {
- *cl= default_cl;
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-/*
- Escape string with backslashes (\)
-
- SYNOPSIS
- escape_string_for_mysql()
- charset_info Charset of the strings
- to Buffer for escaped string
- to_length Length of destination buffer, or 0
- from The string to escape
- length The length of the string to escape
-
- DESCRIPTION
- This escapes the contents of a string by adding backslashes before special
- characters, and turning others into specific escape sequences, such as
- turning newlines into \n and null bytes into \0.
-
- NOTE
- To maintain compatibility with the old C API, to_length may be 0 to mean
- "big enough"
-
- RETURN VALUES
- (size_t) -1 The escaped string did not fit in the to buffer
- # The length of the escaped string
-*/
-
-size_t escape_string_for_mysql(CHARSET_INFO *charset_info,
- char *to, size_t to_length,
- const char *from, size_t length)
-{
- const char *to_start= to;
- const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
- my_bool overflow= FALSE;
-#ifdef USE_MB
- my_bool use_mb_flag= use_mb(charset_info);
-#endif
- for (end= from + length; from < end; from++)
- {
- char escape= 0;
-#ifdef USE_MB
- int tmp_length;
- if (use_mb_flag && (tmp_length= my_ismbchar(charset_info, from, end)))
- {
- if (to + tmp_length > to_end)
- {
- overflow= TRUE;
- break;
- }
- while (tmp_length--)
- *to++= *from++;
- from--;
- continue;
- }
- /*
- If the next character appears to begin a multi-byte character, we
- escape that first byte of that apparent multi-byte character. (The
- character just looks like a multi-byte character -- if it were actually
- a multi-byte character, it would have been passed through in the test
- above.)
-
- Without this check, we can create a problem by converting an invalid
- multi-byte character into a valid one. For example, 0xbf27 is not
- a valid GBK character, but 0xbf5c is. (0x27 = ', 0x5c = \)
- */
- if (use_mb_flag && (tmp_length= my_mbcharlen(charset_info, *from)) > 1)
- escape= *from;
- else
-#endif
- switch (*from) {
- case 0: /* Must be escaped for 'mysql' */
- escape= '0';
- break;
- case '\n': /* Must be escaped for logs */
- escape= 'n';
- break;
- case '\r':
- escape= 'r';
- break;
- case '\\':
- escape= '\\';
- break;
- case '\'':
- escape= '\'';
- break;
- case '"': /* Better safe than sorry */
- escape= '"';
- break;
- case '\032': /* This gives problems on Win32 */
- escape= 'Z';
- break;
- }
- if (escape)
- {
- if (to + 2 > to_end)
- {
- overflow= TRUE;
- break;
- }
- *to++= '\\';
- *to++= escape;
- }
- else
- {
- if (to + 1 > to_end)
- {
- overflow= TRUE;
- break;
- }
- *to++= *from;
- }
- }
- *to= 0;
- return overflow ? (size_t) -1 : (size_t) (to - to_start);
-}
-
-
-#ifdef BACKSLASH_MBTAIL
-static CHARSET_INFO *fs_cset_cache= NULL;
-
-CHARSET_INFO *fs_character_set()
-{
- if (!fs_cset_cache)
- {
- char buf[10]= "cp";
- GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE,
- buf+2, sizeof(buf)-3);
- /*
- We cannot call get_charset_by_name here
- because fs_character_set() is executed before
- LOCK_THD_charset mutex initialization, which
- is used inside get_charset_by_name.
- As we're now interested in cp932 only,
- let's just detect it using strcmp().
- */
- fs_cset_cache= !strcmp(buf, "cp932") ?
- &my_charset_cp932_japanese_ci : &my_charset_bin;
- }
- return fs_cset_cache;
-}
-#endif
-
-/*
- Escape apostrophes by doubling them up
-
- SYNOPSIS
- escape_quotes_for_mysql()
- charset_info Charset of the strings
- to Buffer for escaped string
- to_length Length of destination buffer, or 0
- from The string to escape
- length The length of the string to escape
-
- DESCRIPTION
- This escapes the contents of a string by doubling up any apostrophes that
- it contains. This is used when the NO_BACKSLASH_ESCAPES SQL_MODE is in
- effect on the server.
-
- NOTE
- To be consistent with escape_string_for_mysql(), to_length may be 0 to
- mean "big enough"
-
- RETURN VALUES
- ~0 The escaped string did not fit in the to buffer
- >=0 The length of the escaped string
-*/
-
-size_t escape_quotes_for_mysql(CHARSET_INFO *charset_info,
- char *to, size_t to_length,
- const char *from, size_t length)
-{
- const char *to_start= to;
- const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
- my_bool overflow= FALSE;
-#ifdef USE_MB
- my_bool use_mb_flag= use_mb(charset_info);
-#endif
- for (end= from + length; from < end; from++)
- {
-#ifdef USE_MB
- int tmp_length;
- if (use_mb_flag && (tmp_length= my_ismbchar(charset_info, from, end)))
- {
- if (to + tmp_length > to_end)
- {
- overflow= TRUE;
- break;
- }
- while (tmp_length--)
- *to++= *from++;
- from--;
- continue;
- }
- /*
- We don't have the same issue here with a non-multi-byte character being
- turned into a multi-byte character by the addition of an escaping
- character, because we are only escaping the ' character with itself.
- */
-#endif
- if (*from == '\'')
- {
- if (to + 2 > to_end)
- {
- overflow= TRUE;
- break;
- }
- *to++= '\'';
- *to++= '\'';
- }
- else
- {
- if (to + 1 > to_end)
- {
- overflow= TRUE;
- break;
- }
- *to++= *from;
- }
- }
- *to= 0;
- return overflow ? (ulong)~0 : (ulong) (to - to_start);
-}
diff --git a/dep/mysqllite/mysys/checksum.c b/dep/mysqllite/mysys/checksum.c
deleted file mode 100644
index a96ea31ea0e..00000000000
--- a/dep/mysqllite/mysys/checksum.c
+++ /dev/null
@@ -1,35 +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 <my_global.h>
-#include <my_sys.h>
-#include <zlib.h>
-
-/*
- Calculate a long checksum for a memoryblock.
-
- SYNOPSIS
- my_checksum()
- crc start value for crc
- pos pointer to memory block
- length length of the block
-*/
-
-ha_checksum my_checksum(ha_checksum crc, const uchar *pos, size_t length)
-{
- return (ha_checksum)crc32((uint)crc, pos, (uint)length);
-}
-
diff --git a/dep/mysqllite/mysys/default.c b/dep/mysqllite/mysys/default.c
deleted file mode 100644
index 75eb4709e1e..00000000000
--- a/dep/mysqllite/mysys/default.c
+++ /dev/null
@@ -1,1217 +0,0 @@
-/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 */
-
-/****************************************************************************
- Add all options from files named "group".cnf from the default_directories
- before the command line arguments.
- On Windows defaults will also search in the Windows directory for a file
- called 'group'.ini
- As long as the program uses the last argument for conflicting
- options one only have to add a call to "load_defaults" to enable
- use of default values.
- pre- and end 'blank space' are removed from options and values. The
- following escape sequences are recognized in values: \b \t \n \r \\
-
- The following arguments are handled automaticly; If used, they must be
- first argument on the command line!
- --no-defaults ; no options are read.
- --defaults-file=full-path-to-default-file ; Only this file will be read.
- --defaults-extra-file=full-path-to-default-file ; Read this file before ~/
- --defaults-group-suffix ; Also read groups with concat(group, suffix)
- --print-defaults ; Print the modified command line and exit
-****************************************************************************/
-
-#include "mysys_priv.h"
-#include "m_string.h"
-#include "m_ctype.h"
-#include <my_dir.h>
-#ifdef __WIN__
-#include <winbase.h>
-#endif
-
-/**
- arguments separator
-
- load_defaults() loads arguments from config file and put them
- before the arguments from command line, this separator is used to
- separate the arguments loaded from config file and arguments user
- provided on command line.
-
- Options with value loaded from config file are always in the form
- '--option=value', while for command line options, the value can be
- given as the next argument. Thus we used a separator so that
- handle_options() can distinguish them.
-
- Note: any other places that does not need to distinguish them
- should skip the separator.
-
- The content of arguments separator does not matter, one should only
- check the pointer, use "----args-separator----" here to ease debug
- if someone misused it.
-
- See BUG#25192
-*/
-const char *args_separator= "----args-separator----";
-const char *my_defaults_file=0;
-const char *my_defaults_group_suffix=0;
-const char *my_defaults_extra_file=0;
-
-static char my_defaults_file_buffer[FN_REFLEN];
-static char my_defaults_extra_file_buffer[FN_REFLEN];
-
-static my_bool defaults_already_read= FALSE;
-
-/* Which directories are searched for options (and in which order) */
-
-#define MAX_DEFAULT_DIRS 6
-#define DEFAULT_DIRS_SIZE (MAX_DEFAULT_DIRS + 1) /* Terminate with NULL */
-static const char **default_directories = NULL;
-
-#ifdef __WIN__
-static const char *f_extensions[]= { ".ini", ".cnf", 0 };
-#define NEWLINE "\r\n"
-#else
-static const char *f_extensions[]= { ".cnf", 0 };
-#define NEWLINE "\n"
-#endif
-
-static int handle_default_option(void *in_ctx, const char *group_name,
- const char *option);
-
-/*
- This structure defines the context that we pass to callback
- function 'handle_default_option' used in search_default_file
- to process each option. This context is used if search_default_file
- was called from load_defaults.
-*/
-
-struct handle_option_ctx
-{
- MEM_ROOT *alloc;
- DYNAMIC_ARRAY *args;
- TYPELIB *group;
-};
-
-static int search_default_file(Process_option_func func, void *func_ctx,
- const char *dir, const char *config_file);
-static int search_default_file_with_ext(Process_option_func func,
- void *func_ctx,
- const char *dir, const char *ext,
- const char *config_file, int recursion_level);
-
-
-/**
- Create the list of default directories.
-
- @param alloc MEM_ROOT where the list of directories is stored
-
- @details
- The directories searched, in order, are:
- - Windows: GetSystemWindowsDirectory()
- - Windows: GetWindowsDirectory()
- - Windows: C:/
- - Windows: Directory above where the executable is located
- - Unix: /etc/
- - Unix: /etc/mysql/
- - Unix: --sysconfdir=<path> (compile-time option)
- - ALL: getenv(DEFAULT_HOME_ENV)
- - ALL: --defaults-extra-file=<path> (run-time option)
- - Unix: ~/
-
- On all systems, if a directory is already in the list, it will be moved
- to the end of the list. This avoids reading defaults files multiple times,
- while ensuring the correct precedence.
-
- @retval NULL Failure (out of memory, probably)
- @retval other Pointer to NULL-terminated array of default directories
-*/
-
-static const char **init_default_directories(MEM_ROOT *alloc);
-
-
-static char *remove_end_comment(char *ptr);
-
-
-/*
- Expand a file name so that the current working directory is added if
- the name is relative.
-
- RETURNS
- 0 All OK
- 2 Out of memory or path to long
- 3 Not able to get working directory
- */
-
-static int
-fn_expand(const char *filename, char *result_buf)
-{
- char dir[FN_REFLEN];
- const int flags= MY_UNPACK_FILENAME | MY_SAFE_PATH | MY_RELATIVE_PATH;
- DBUG_ENTER("fn_expand");
- DBUG_PRINT("enter", ("filename: %s, result_buf: 0x%lx",
- filename, (unsigned long) result_buf));
- if (my_getwd(dir, sizeof(dir), MYF(0)))
- DBUG_RETURN(3);
- DBUG_PRINT("debug", ("dir: %s", dir));
- if (fn_format(result_buf, filename, dir, NULL, flags) == NULL)
- DBUG_RETURN(2);
- DBUG_PRINT("return", ("result: %s", result_buf));
- DBUG_RETURN(0);
-}
-
-/*
- Process config files in default directories.
-
- SYNOPSIS
- my_search_option_files()
- conf_file Basename for configuration file to search for.
- If this is a path, then only this file is read.
- argc Pointer to argc of original program
- argv Pointer to argv of original program
- args_used Pointer to variable for storing the number of
- arguments used.
- func Pointer to the function to process options
- func_ctx It's context. Usually it is the structure to
- store additional options.
- DESCRIPTION
- Process the default options from argc & argv
- Read through each found config file looks and calls 'func' to process
- each option.
-
- NOTES
- --defaults-group-suffix is only processed if we are called from
- load_defaults().
-
-
- RETURN
- 0 ok
- 1 given cinf_file doesn't exist
- 2 out of memory
- 3 Can't get current working directory
-
- The global variable 'my_defaults_group_suffix' is updated with value for
- --defaults_group_suffix
-*/
-
-int my_search_option_files(const char *conf_file, int *argc, char ***argv,
- uint *args_used, Process_option_func func,
- void *func_ctx, const char **default_directories)
-{
- const char **dirs, *forced_default_file, *forced_extra_defaults;
- int error= 0;
- DBUG_ENTER("my_search_option_files");
-
- /* Check if we want to force the use a specific default file */
- *args_used+= get_defaults_options(*argc - *args_used, *argv + *args_used,
- (char **) &forced_default_file,
- (char **) &forced_extra_defaults,
- (char **) &my_defaults_group_suffix);
-
- if (! my_defaults_group_suffix)
- my_defaults_group_suffix= getenv(STRINGIFY_ARG(DEFAULT_GROUP_SUFFIX_ENV));
-
- if (forced_extra_defaults && !defaults_already_read)
- {
- int error= fn_expand(forced_extra_defaults, my_defaults_extra_file_buffer);
- if (error)
- DBUG_RETURN(error);
- my_defaults_extra_file= my_defaults_extra_file_buffer;
- }
-
- if (forced_default_file && !defaults_already_read)
- {
- int error= fn_expand(forced_default_file, my_defaults_file_buffer);
- if (error)
- DBUG_RETURN(error);
- my_defaults_file= my_defaults_file_buffer;
- }
-
- defaults_already_read= TRUE;
-
- /*
- We can only handle 'defaults-group-suffix' if we are called from
- load_defaults() as otherwise we can't know the type of 'func_ctx'
- */
-
- if (my_defaults_group_suffix && func == handle_default_option)
- {
- /* Handle --defaults-group-suffix= */
- uint i;
- const char **extra_groups;
- const size_t instance_len= strlen(my_defaults_group_suffix);
- struct handle_option_ctx *ctx= (struct handle_option_ctx*) func_ctx;
- char *ptr;
- TYPELIB *group= ctx->group;
-
- if (!(extra_groups=
- (const char**)alloc_root(ctx->alloc,
- (2*group->count+1)*sizeof(char*))))
- DBUG_RETURN(2);
-
- for (i= 0; i < group->count; i++)
- {
- size_t len;
- extra_groups[i]= group->type_names[i]; /** copy group */
-
- len= strlen(extra_groups[i]);
- if (!(ptr= alloc_root(ctx->alloc, (uint) (len+instance_len+1))))
- DBUG_RETURN(2);
-
- extra_groups[i+group->count]= ptr;
-
- /** Construct new group */
- memcpy(ptr, extra_groups[i], len);
- memcpy(ptr+len, my_defaults_group_suffix, instance_len+1);
- }
-
- group->count*= 2;
- group->type_names= extra_groups;
- group->type_names[group->count]= 0;
- }
-
- if (my_defaults_file)
- {
- if ((error= search_default_file_with_ext(func, func_ctx, "", "",
- my_defaults_file, 0)) < 0)
- goto err;
- if (error > 0)
- {
- fprintf(stderr, "Could not open required defaults file: %s\n",
- my_defaults_file);
- goto err;
- }
- }
- else if (dirname_length(conf_file))
- {
- if ((error= search_default_file(func, func_ctx, NullS, conf_file)) < 0)
- goto err;
- }
- else
- {
- for (dirs= default_directories ; *dirs; dirs++)
- {
- if (**dirs)
- {
- if (search_default_file(func, func_ctx, *dirs, conf_file) < 0)
- goto err;
- }
- else if (my_defaults_extra_file)
- {
- if ((error= search_default_file_with_ext(func, func_ctx, "", "",
- my_defaults_extra_file, 0)) < 0)
- goto err; /* Fatal error */
- if (error > 0)
- {
- fprintf(stderr, "Could not open required defaults file: %s\n",
- my_defaults_extra_file);
- goto err;
- }
- }
- }
- }
-
- DBUG_RETURN(0);
-
-err:
- fprintf(stderr,"Fatal error in defaults handling. Program aborted\n");
- DBUG_RETURN(1);
-}
-
-
-/*
- The option handler for load_defaults.
-
- SYNOPSIS
- handle_deault_option()
- in_ctx Handler context. In this case it is a
- 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). 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
- to the array if yes. Some other handler can record, for instance, all
- groups and their options, not knowing in advance the names and amount of
- groups.
-
- RETURN
- 0 - ok
- 1 - error occured
-*/
-
-static int handle_default_option(void *in_ctx, const char *group_name,
- const char *option)
-{
- 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, strlen(option) + 1)))
- return 1;
- if (insert_dynamic(ctx->args, (uchar*) &tmp))
- return 1;
- strmov(tmp, option);
- }
-
- return 0;
-}
-
-
-/*
- Gets options from the command line
-
- SYNOPSIS
- get_defaults_options()
- argc Pointer to argc of original program
- argv Pointer to argv of original program
- defaults --defaults-file option
- extra_defaults --defaults-extra-file option
-
- RETURN
- # Number of arguments used from *argv
- defaults and extra_defaults will be set to option of the appropriate
- items of argv array, or to NULL if there are no such options
-*/
-
-int get_defaults_options(int argc, char **argv,
- char **defaults,
- char **extra_defaults,
- char **group_suffix)
-{
- int org_argc= argc, prev_argc= 0;
- *defaults= *extra_defaults= *group_suffix= 0;
-
- while (argc >= 2 && argc != prev_argc)
- {
- /* Skip program name or previously handled argument */
- argv++;
- prev_argc= argc; /* To check if we found */
- if (!*defaults && is_prefix(*argv,"--defaults-file="))
- {
- *defaults= *argv + sizeof("--defaults-file=")-1;
- argc--;
- continue;
- }
- if (!*extra_defaults && is_prefix(*argv,"--defaults-extra-file="))
- {
- *extra_defaults= *argv + sizeof("--defaults-extra-file=")-1;
- argc--;
- continue;
- }
- if (!*group_suffix && is_prefix(*argv, "--defaults-group-suffix="))
- {
- *group_suffix= *argv + sizeof("--defaults-group-suffix=")-1;
- argc--;
- continue;
- }
- }
- return org_argc - argc;
-}
-
-/*
- Wrapper around my_load_defaults() for interface compatibility.
-
- SYNOPSIS
- load_defaults()
- conf_file Basename for configuration file to search for.
- If this is a path, then only this file is read.
- groups Which [group] entrys to read.
- Points to an null terminated array of pointers
- argc Pointer to argc of original program
- argv Pointer to argv of original program
-
- NOTES
-
- This function is NOT thread-safe as it uses a global pointer internally.
- See also notes for my_load_defaults().
-
- RETURN
- 0 ok
- 1 The given conf_file didn't exists
-*/
-int load_defaults(const char *conf_file, const char **groups,
- int *argc, char ***argv)
-{
- return my_load_defaults(conf_file, groups, argc, argv, &default_directories);
-}
-
-/*
- Read options from configurations files
-
- SYNOPSIS
- my_load_defaults()
- conf_file Basename for configuration file to search for.
- If this is a path, then only this file is read.
- groups Which [group] entrys to read.
- Points to an null terminated array of pointers
- argc Pointer to argc of original program
- argv Pointer to argv of original program
- default_directories Pointer to a location where a pointer to the list
- of default directories will be stored
-
- IMPLEMENTATION
-
- Read options from configuration files and put them BEFORE the arguments
- that are already in argc and argv. This way the calling program can
- easily command line options override options in configuration files
-
- NOTES
- In case of fatal error, the function will print a warning and do
- exit(1)
-
- To free used memory one should call free_defaults() with the argument
- that was put in *argv
-
- RETURN
- - If successful, 0 is returned. If 'default_directories' is not NULL,
- a pointer to the array of default directory paths is stored to a location
- it points to. That stored value must be passed to my_search_option_files()
- later.
-
- - 1 is returned if the given conf_file didn't exist. In this case, the
- value pointed to by default_directories is undefined.
-*/
-
-
-int my_load_defaults(const char *conf_file, const char **groups,
- int *argc, char ***argv, const char ***default_directories)
-{
- DYNAMIC_ARRAY args;
- TYPELIB group;
- my_bool found_print_defaults= 0;
- uint args_used= 0;
- int error= 0;
- MEM_ROOT alloc;
- char *ptr,**res;
- struct handle_option_ctx ctx;
- const char **dirs;
- DBUG_ENTER("load_defaults");
-
- init_alloc_root(&alloc,512,0);
- if ((dirs= init_default_directories(&alloc)) == NULL)
- goto err;
- /*
- Check if the user doesn't want any default option processing
- --no-defaults is always the first option
- */
- if (*argc >= 2 && !strcmp(argv[0][1],"--no-defaults"))
- {
- /* remove the --no-defaults argument and return only the other arguments */
- uint i;
- if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+
- (*argc + 1)*sizeof(char*))))
- goto err;
- res= (char**) (ptr+sizeof(alloc));
- res[0]= **argv; /* Copy program name */
- /* set arguments separator */
- res[1]= (char *)args_separator;
- for (i=2 ; i < (uint) *argc ; i++)
- res[i]=argv[0][i];
- res[i]=0; /* End pointer */
- *argv=res;
- *(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */
- if (default_directories)
- *default_directories= dirs;
- DBUG_RETURN(0);
- }
-
- group.count=0;
- group.name= "defaults";
- group.type_names= groups;
-
- for (; *groups ; groups++)
- group.count++;
-
- if (my_init_dynamic_array(&args, sizeof(char*),*argc, 32))
- goto err;
-
- ctx.alloc= &alloc;
- ctx.args= &args;
- ctx.group= &group;
-
- if ((error= my_search_option_files(conf_file, argc, argv, &args_used,
- handle_default_option, (void *) &ctx,
- dirs)))
- {
- free_root(&alloc,MYF(0));
- DBUG_RETURN(error);
- }
- /*
- Here error contains <> 0 only if we have a fully specified conf_file
- or a forced default file
- */
- if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+
- (args.elements + *argc + 1 + 1) *sizeof(char*))))
- goto err;
- res= (char**) (ptr+sizeof(alloc));
-
- /* copy name + found arguments + command line arguments to new array */
- res[0]= argv[0][0]; /* Name MUST be set, even by embedded library */
- memcpy((uchar*) (res+1), args.buffer, args.elements*sizeof(char*));
- /* Skip --defaults-xxx options */
- (*argc)-= args_used;
- (*argv)+= args_used;
-
- /*
- Check if we wan't to see the new argument list
- This options must always be the last of the default options
- */
- if (*argc >= 2 && !strcmp(argv[0][1],"--print-defaults"))
- {
- found_print_defaults=1;
- --*argc; ++*argv; /* skip argument */
- }
-
- /* set arguments separator for arguments from config file and
- command line */
- res[args.elements+1]= (char *)args_separator;
-
- if (*argc)
- memcpy((uchar*) (res+1+args.elements+1), (char*) ((*argv)+1),
- (*argc-1)*sizeof(char*));
- res[args.elements+ *argc+1]=0; /* last null */
-
- (*argc)+=args.elements+1;
- *argv= (char**) res;
- *(MEM_ROOT*) ptr= alloc; /* Save alloc root for free */
- delete_dynamic(&args);
- if (found_print_defaults)
- {
- int i;
- printf("%s would have been started with the following arguments:\n",
- **argv);
- for (i=1 ; i < *argc ; i++)
- if ((*argv)[i] != args_separator) /* skip arguments separator */
- printf("%s ", (*argv)[i]);
- puts("");
- exit(0);
- }
-
- if (default_directories)
- *default_directories= dirs;
-
- DBUG_RETURN(0);
-
- err:
- fprintf(stderr,"Fatal error in defaults handling. Program aborted\n");
- exit(1);
- return 0; /* Keep compiler happy */
-}
-
-
-void free_defaults(char **argv)
-{
- MEM_ROOT ptr;
- memcpy(&ptr, ((char *) argv) - sizeof(ptr), sizeof(ptr));
- free_root(&ptr,MYF(0));
-}
-
-
-static int search_default_file(Process_option_func opt_handler,
- void *handler_ctx,
- const char *dir,
- const char *config_file)
-{
- char **ext;
- const char *empty_list[]= { "", 0 };
- my_bool have_ext= fn_ext(config_file)[0] != 0;
- const char **exts_to_use= have_ext ? empty_list : f_extensions;
-
- for (ext= (char**) exts_to_use; *ext; ext++)
- {
- int error;
- if ((error= search_default_file_with_ext(opt_handler, handler_ctx,
- dir, *ext,
- config_file, 0)) < 0)
- return error;
- }
- return 0;
-}
-
-
-/*
- Skip over keyword and get argument after keyword
-
- SYNOPSIS
- get_argument()
- keyword Include directive keyword
- kwlen Length of keyword
- ptr Pointer to the keword in the line under process
- line line number
-
- RETURN
- 0 error
- # Returns pointer to the argument after the keyword.
-*/
-
-static char *get_argument(const char *keyword, size_t kwlen,
- char *ptr, char *name, uint line)
-{
- char *end;
-
- /* Skip over "include / includedir keyword" and following whitespace */
-
- for (ptr+= kwlen - 1;
- my_isspace(&my_charset_latin1, ptr[0]);
- ptr++)
- {}
-
- /*
- Trim trailing whitespace from directory name
- The -1 below is for the newline added by fgets()
- Note that my_isspace() is true for \r and \n
- */
- for (end= ptr + strlen(ptr) - 1;
- my_isspace(&my_charset_latin1, *(end - 1));
- end--)
- {}
- end[0]= 0; /* Cut off end space */
-
- /* Print error msg if there is nothing after !include* directive */
- if (end <= ptr)
- {
- fprintf(stderr,
- "error: Wrong '!%s' directive in config file: %s at line %d\n",
- keyword, name, line);
- return 0;
- }
- return ptr;
-}
-
-
-/*
- Open a configuration file (if exists) and read given options from it
-
- SYNOPSIS
- search_default_file_with_ext()
- opt_handler Option handler function. It is used to process
- every separate option.
- handler_ctx Pointer to the structure to store actual
- parameters of the function.
- dir directory to read
- ext Extension for configuration file
- config_file Name of configuration file
- group groups to read
- recursion_level the level of recursion, got while processing
- "!include" or "!includedir"
-
- RETURN
- 0 Success
- -1 Fatal error, abort
- 1 File not found (Warning)
-*/
-
-static int search_default_file_with_ext(Process_option_func opt_handler,
- void *handler_ctx,
- const char *dir,
- const char *ext,
- const char *config_file,
- int recursion_level)
-{
- char name[FN_REFLEN + 10], buff[4096], curr_gr[4096], *ptr, *end, **tmp_ext;
- char *value, option[4096+2], tmp[FN_REFLEN];
- static const char includedir_keyword[]= "includedir";
- static const char include_keyword[]= "include";
- const int max_recursion_level= 10;
- MYSQL_FILE *fp;
- uint line=0;
- my_bool found_group=0;
- uint i;
- MY_DIR *search_dir;
- FILEINFO *search_file;
-
- if ((dir ? strlen(dir) : 0 )+strlen(config_file) >= FN_REFLEN-3)
- return 0; /* Ignore wrong paths */
- if (dir)
- {
- end=convert_dirname(name, dir, NullS);
- if (dir[0] == FN_HOMELIB) /* Add . to filenames in home */
- *end++='.';
- strxmov(end,config_file,ext,NullS);
- }
- else
- {
- strmov(name,config_file);
- }
- fn_format(name,name,"","",4);
-#if !defined(__WIN__)
- {
- MY_STAT stat_info;
- if (!my_stat(name,&stat_info,MYF(0)))
- return 1;
- /*
- Ignore world-writable regular files.
- This is mainly done to protect us to not read a file created by
- the mysqld server, but the check is still valid in most context.
- */
- if ((stat_info.st_mode & S_IWOTH) &&
- (stat_info.st_mode & S_IFMT) == S_IFREG)
- {
- fprintf(stderr, "Warning: World-writable config file '%s' is ignored\n",
- name);
- return 0;
- }
- }
-#endif
- if (!(fp= mysql_file_fopen(key_file_cnf, name, O_RDONLY, MYF(0))))
- return 1; /* Ignore wrong files */
-
- while (mysql_file_fgets(buff, sizeof(buff) - 1, fp))
- {
- line++;
- /* Ignore comment and empty lines */
- for (ptr= buff; my_isspace(&my_charset_latin1, *ptr); ptr++)
- {}
-
- if (*ptr == '#' || *ptr == ';' || !*ptr)
- continue;
-
- /* Configuration File Directives */
- if ((*ptr == '!'))
- {
- if (recursion_level >= max_recursion_level)
- {
- for (end= ptr + strlen(ptr) - 1;
- my_isspace(&my_charset_latin1, *(end - 1));
- end--)
- {}
- end[0]= 0;
- fprintf(stderr,
- "Warning: skipping '%s' directive as maximum include"
- "recursion level was reached in file %s at line %d\n",
- ptr, name, line);
- continue;
- }
-
- /* skip over `!' and following whitespace */
- for (++ptr; my_isspace(&my_charset_latin1, ptr[0]); ptr++)
- {}
-
- if ((!strncmp(ptr, includedir_keyword,
- sizeof(includedir_keyword) - 1)) &&
- my_isspace(&my_charset_latin1, ptr[sizeof(includedir_keyword) - 1]))
- {
- if (!(ptr= get_argument(includedir_keyword,
- sizeof(includedir_keyword),
- ptr, name, line)))
- goto err;
-
- if (!(search_dir= my_dir(ptr, MYF(MY_WME))))
- goto err;
-
- for (i= 0; i < (uint) search_dir->number_off_files; i++)
- {
- search_file= search_dir->dir_entry + i;
- ext= fn_ext(search_file->name);
-
- /* check extension */
- for (tmp_ext= (char**) f_extensions; *tmp_ext; tmp_ext++)
- {
- if (!strcmp(ext, *tmp_ext))
- break;
- }
-
- if (*tmp_ext)
- {
- fn_format(tmp, search_file->name, ptr, "",
- MY_UNPACK_FILENAME | MY_SAFE_PATH);
-
- search_default_file_with_ext(opt_handler, handler_ctx, "", "", tmp,
- recursion_level + 1);
- }
- }
-
- my_dirend(search_dir);
- }
- else if ((!strncmp(ptr, include_keyword, sizeof(include_keyword) - 1)) &&
- my_isspace(&my_charset_latin1, ptr[sizeof(include_keyword)-1]))
- {
- if (!(ptr= get_argument(include_keyword,
- sizeof(include_keyword), ptr,
- name, line)))
- goto err;
-
- search_default_file_with_ext(opt_handler, handler_ctx, "", "", ptr,
- recursion_level + 1);
- }
-
- continue;
- }
-
- if (*ptr == '[') /* Group name */
- {
- found_group=1;
- if (!(end=(char *) strchr(++ptr,']')))
- {
- fprintf(stderr,
- "error: Wrong group definition in config file: %s at line %d\n",
- name,line);
- goto err;
- }
- /* Remove end space */
- for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ;
- end[0]=0;
-
- strmake(curr_gr, ptr, min((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
-
- /* signal that a new group is found */
- opt_handler(handler_ctx, curr_gr, NULL);
-
- continue;
- }
- if (!found_group)
- {
- fprintf(stderr,
- "error: Found option without preceding group in config file: %s at line: %d\n",
- name,line);
- goto err;
- }
-
-
- end= remove_end_comment(ptr);
- if ((value= strchr(ptr, '=')))
- end= value; /* Option without argument */
- for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ;
- if (!value)
- {
- strmake(strmov(option,"--"),ptr, (size_t) (end-ptr));
- if (opt_handler(handler_ctx, curr_gr, option))
- goto err;
- }
- else
- {
- /* Remove pre- and end space */
- char *value_end;
- for (value++ ; my_isspace(&my_charset_latin1,*value); value++) ;
- value_end=strend(value);
- /*
- We don't have to test for value_end >= value as we know there is
- an '=' before
- */
- for ( ; my_isspace(&my_charset_latin1,value_end[-1]) ; value_end--) ;
- if (value_end < value) /* Empty string */
- value_end=value;
-
- /* remove quotes around argument */
- if ((*value == '\"' || *value == '\'') && /* First char is quote */
- (value + 1 < value_end ) && /* String is longer than 1 */
- *value == value_end[-1] ) /* First char is equal to last char */
- {
- value++;
- value_end--;
- }
- ptr=strnmov(strmov(option,"--"),ptr,(size_t) (end-ptr));
- *ptr++= '=';
-
- for ( ; value != value_end; value++)
- {
- if (*value == '\\' && value != value_end-1)
- {
- switch(*++value) {
- case 'n':
- *ptr++='\n';
- break;
- case 't':
- *ptr++= '\t';
- break;
- case 'r':
- *ptr++ = '\r';
- break;
- case 'b':
- *ptr++ = '\b';
- break;
- case 's':
- *ptr++= ' '; /* space */
- break;
- case '\"':
- *ptr++= '\"';
- break;
- case '\'':
- *ptr++= '\'';
- break;
- case '\\':
- *ptr++= '\\';
- break;
- default: /* Unknown; Keep '\' */
- *ptr++= '\\';
- *ptr++= *value;
- break;
- }
- }
- else
- *ptr++= *value;
- }
- *ptr=0;
- if (opt_handler(handler_ctx, curr_gr, option))
- goto err;
- }
- }
- mysql_file_fclose(fp, MYF(0));
- return(0);
-
- err:
- mysql_file_fclose(fp, MYF(0));
- return -1; /* Fatal error */
-}
-
-
-static char *remove_end_comment(char *ptr)
-{
- char quote= 0; /* we are inside quote marks */
- char escape= 0; /* symbol is protected by escape chagacter */
-
- for (; *ptr; ptr++)
- {
- if ((*ptr == '\'' || *ptr == '\"') && !escape)
- {
- if (!quote)
- quote= *ptr;
- else if (quote == *ptr)
- quote= 0;
- }
- /* We are not inside a string */
- if (!quote && *ptr == '#')
- {
- *ptr= 0;
- return ptr;
- }
- escape= (quote && *ptr == '\\' && !escape);
- }
- return ptr;
-}
-
-
-void my_print_default_files(const char *conf_file)
-{
- const char *empty_list[]= { "", 0 };
- my_bool have_ext= fn_ext(conf_file)[0] != 0;
- const char **exts_to_use= have_ext ? empty_list : f_extensions;
- char name[FN_REFLEN], **ext;
-
- puts("\nDefault options are read from the following files in the given order:");
-
- if (dirname_length(conf_file))
- fputs(conf_file,stdout);
- else
- {
- const char **dirs;
- MEM_ROOT alloc;
- init_alloc_root(&alloc,512,0);
-
- if ((dirs= init_default_directories(&alloc)) == NULL)
- {
- fputs("Internal error initializing default directories list", stdout);
- }
- else
- {
- for ( ; *dirs; dirs++)
- {
- for (ext= (char**) exts_to_use; *ext; ext++)
- {
- const char *pos;
- char *end;
- if (**dirs)
- pos= *dirs;
- else if (my_defaults_extra_file)
- pos= my_defaults_extra_file;
- else
- continue;
- end= convert_dirname(name, pos, NullS);
- if (name[0] == FN_HOMELIB) /* Add . to filenames in home */
- *end++= '.';
- strxmov(end, conf_file, *ext, " ", NullS);
- fputs(name, stdout);
- }
- }
- }
-
- free_root(&alloc, MYF(0));
- }
- puts("");
-}
-
-void print_defaults(const char *conf_file, const char **groups)
-{
- const char **groups_save= groups;
- my_print_default_files(conf_file);
-
- fputs("The following groups are read:",stdout);
- for ( ; *groups ; groups++)
- {
- fputc(' ',stdout);
- fputs(*groups,stdout);
- }
-
- if (my_defaults_group_suffix)
- {
- groups= groups_save;
- for ( ; *groups ; groups++)
- {
- fputc(' ',stdout);
- fputs(*groups,stdout);
- fputs(my_defaults_group_suffix,stdout);
- }
- }
- puts("\nThe following options may be given as the first argument:\n\
---print-defaults Print the program argument list and exit.\n\
---no-defaults Don't read default options from any option file.\n\
---defaults-file=# Only read default options from the given file #.\n\
---defaults-extra-file=# Read this file after the global files are read.");
-}
-
-
-static int add_directory(MEM_ROOT *alloc, const char *dir, const char **dirs)
-{
- char buf[FN_REFLEN];
- size_t len;
- char *p;
- my_bool err __attribute__((unused));
-
- len= normalize_dirname(buf, dir);
- if (!(p= strmake_root(alloc, buf, len)))
- return 1; /* Failure */
- /* Should never fail if DEFAULT_DIRS_SIZE is correct size */
- err= array_append_string_unique(p, dirs, DEFAULT_DIRS_SIZE);
- DBUG_ASSERT(err == FALSE);
-
- return 0;
-}
-
-
-#ifdef __WIN__
-/*
- This wrapper for GetSystemWindowsDirectory() will dynamically bind to the
- function if it is available, emulate it on NT4 Terminal Server by stripping
- the \SYSTEM32 from the end of the results of GetSystemDirectory(), or just
- return GetSystemDirectory().
- */
-
-typedef UINT (WINAPI *GET_SYSTEM_WINDOWS_DIRECTORY)(LPSTR, UINT);
-
-static size_t my_get_system_windows_directory(char *buffer, size_t size)
-{
- size_t count;
- GET_SYSTEM_WINDOWS_DIRECTORY
- func_ptr= (GET_SYSTEM_WINDOWS_DIRECTORY)
- GetProcAddress(GetModuleHandle("kernel32.dll"),
- "GetSystemWindowsDirectoryA");
-
- if (func_ptr)
- return func_ptr(buffer, (uint) size);
-
- /*
- Windows NT 4.0 Terminal Server Edition:
- To retrieve the shared Windows directory, call GetSystemDirectory and
- trim the "System32" element from the end of the returned path.
- */
- count= GetSystemDirectory(buffer, (uint) size);
- if (count > 8 && stricmp(buffer+(count-8), "\\System32") == 0)
- {
- count-= 8;
- buffer[count] = '\0';
- }
- return count;
-}
-
-
-static const char *my_get_module_parent(char *buf, size_t size)
-{
- char *last= NULL;
- char *end;
- if (!GetModuleFileName(NULL, buf, (DWORD) size))
- return NULL;
- end= strend(buf);
-
- /*
- Look for the second-to-last \ in the filename, but hang on
- to a pointer after the last \ in case we're in the root of
- a drive.
- */
- for ( ; end > buf; end--)
- {
- if (*end == FN_LIBCHAR)
- {
- if (last)
- {
- /* Keep the last '\' as this works both with D:\ and a directory */
- end[1]= 0;
- break;
- }
- last= end;
- }
- }
-
- return buf;
-}
-#endif /* __WIN__ */
-
-
-static const char **init_default_directories(MEM_ROOT *alloc)
-{
- const char **dirs;
- char *env;
- int errors= 0;
-
- dirs= (const char **)alloc_root(alloc, DEFAULT_DIRS_SIZE * sizeof(char *));
- if (dirs == NULL)
- return NULL;
- bzero((char *) dirs, DEFAULT_DIRS_SIZE * sizeof(char *));
-
-#ifdef __WIN__
-
- {
- char fname_buffer[FN_REFLEN];
- if (my_get_system_windows_directory(fname_buffer, sizeof(fname_buffer)))
- errors += add_directory(alloc, fname_buffer, dirs);
-
- if (GetWindowsDirectory(fname_buffer, sizeof(fname_buffer)))
- errors += add_directory(alloc, fname_buffer, dirs);
-
- errors += add_directory(alloc, "C:/", dirs);
-
- if (my_get_module_parent(fname_buffer, sizeof(fname_buffer)) != NULL)
- errors += add_directory(alloc, fname_buffer, dirs);
- }
-
-#else
-
- errors += add_directory(alloc, "/etc/", dirs);
- errors += add_directory(alloc, "/etc/mysql/", dirs);
-
-#if defined(DEFAULT_SYSCONFDIR)
- if (DEFAULT_SYSCONFDIR[0])
- errors += add_directory(alloc, DEFAULT_SYSCONFDIR, dirs);
-#endif /* DEFAULT_SYSCONFDIR */
-
-#endif
-
- if ((env= getenv(STRINGIFY_ARG(DEFAULT_HOME_ENV))))
- errors += add_directory(alloc, env, dirs);
-
- /* Placeholder for --defaults-extra-file=<path> */
- errors += add_directory(alloc, "", dirs);
-
-#if !defined(__WIN__)
- errors += add_directory(alloc, "~/", dirs);
-#endif
-
- return (errors > 0 ? NULL : dirs);
-}
diff --git a/dep/mysqllite/mysys/errors.c b/dep/mysqllite/mysys/errors.c
deleted file mode 100644
index c74ed292906..00000000000
--- a/dep/mysqllite/mysys/errors.c
+++ /dev/null
@@ -1,119 +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"
-
-#ifndef SHARED_LIBRARY
-
-const char *globerrs[GLOBERRS]=
-{
- "Can't create/write to file '%s' (Errcode: %d)",
- "Error reading file '%s' (Errcode: %d)",
- "Error writing file '%s' (Errcode: %d)",
- "Error on close of '%s' (Errcode: %d)",
- "Out of memory (Needed %u bytes)",
- "Error on delete of '%s' (Errcode: %d)",
- "Error on rename of '%s' to '%s' (Errcode: %d)",
- "",
- "Unexpected eof found when reading file '%s' (Errcode: %d)",
- "Can't lock file (Errcode: %d)",
- "Can't unlock file (Errcode: %d)",
- "Can't read dir of '%s' (Errcode: %d)",
- "Can't get stat of '%s' (Errcode: %d)",
- "Can't change size of file (Errcode: %d)",
- "Can't open stream from handle (Errcode: %d)",
- "Can't get working dirctory (Errcode: %d)",
- "Can't change dir to '%s' (Errcode: %d)",
- "Warning: '%s' had %d links",
- "Warning: %d files and %d streams is left open\n",
- "Disk is full writing '%s' (Errcode: %d). Waiting for someone to free space... (Expect up to %d secs delay for server to continue after freeing disk space)",
- "Can't create directory '%s' (Errcode: %d)",
- "Character set '%s' is not a compiled character set and is not specified in the '%s' file",
- "Out of resources when opening file '%s' (Errcode: %d)",
- "Can't read value for symlink '%s' (Error %d)",
- "Can't create symlink '%s' pointing at '%s' (Error %d)",
- "Error on realpath() on '%s' (Error %d)",
- "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",
- "Can't change ownership of the file '%s' (Errcode: %d)",
- "Can't change permissions of the file '%s' (Errcode: %d)",
- "Can't seek in file '%s' (Errcode: %d)"
-};
-
-void init_glob_errs(void)
-{
- /* This is now done statically. */
-}
-
-#else
-
-void init_glob_errs()
-{
- EE(EE_CANTCREATEFILE) = "Can't create/write to file '%s' (Errcode: %d)";
- EE(EE_READ) = "Error reading file '%s' (Errcode: %d)";
- EE(EE_WRITE) = "Error writing file '%s' (Errcode: %d)";
- EE(EE_BADCLOSE) = "Error on close of '%'s (Errcode: %d)";
- EE(EE_OUTOFMEMORY) = "Out of memory (Needed %u bytes)";
- EE(EE_DELETE) = "Error on delete of '%s' (Errcode: %d)";
- EE(EE_LINK) = "Error on rename of '%s' to '%s' (Errcode: %d)";
- EE(EE_EOFERR) = "Unexpected eof found when reading file '%s' (Errcode: %d)";
- EE(EE_CANTLOCK) = "Can't lock file (Errcode: %d)";
- EE(EE_CANTUNLOCK) = "Can't unlock file (Errcode: %d)";
- EE(EE_DIR) = "Can't read dir of '%s' (Errcode: %d)";
- EE(EE_STAT) = "Can't get stat of '%s' (Errcode: %d)";
- EE(EE_CANT_CHSIZE) = "Can't change size of file (Errcode: %d)";
- EE(EE_CANT_OPEN_STREAM)= "Can't open stream from handle (Errcode: %d)";
- EE(EE_GETWD) = "Can't get working directory (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) = "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";
- EE(EE_OUT_OF_FILERESOURCES)="Out of resources when opening file '%s' (Errcode: %d)";
- EE(EE_CANT_READLINK)= "Can't read value for symlink '%s' (Error %d)";
- EE(EE_CANT_SYMLINK)= "Can't create symlink '%s' pointing at '%s' (Error %d)";
- EE(EE_REALPATH)= "Error on realpath() on '%s' (Error %d)";
- 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";
- EE(EE_CHANGE_OWNERSHIP) = "Can't change ownership of the file '%s' (Errcode: %d)";
- EE(EE_CHANGE_PERMISSIONS) = "Can't change permissions of the file '%s' (Errcode: %d)";
- EE(EE_CANT_SEEK) = "Can't seek in file '%s' (Errcode: %d)";
-}
-#endif
-
-void wait_for_free_space(const char *filename, int errors)
-{
- if (errors == 0)
- my_error(EE_DISK_FULL,MYF(ME_BELL | ME_NOREFRESH),
- filename,my_errno,MY_WAIT_FOR_USER_TO_FIX_PANIC);
- if (!(errors % MY_WAIT_GIVE_USER_A_MESSAGE))
- my_printf_error(EE_DISK_FULL,
- "Retry in %d secs. Message reprinted in %d secs",
- MYF(ME_BELL | ME_NOREFRESH),
- MY_WAIT_FOR_USER_TO_FIX_PANIC,
- MY_WAIT_GIVE_USER_A_MESSAGE * MY_WAIT_FOR_USER_TO_FIX_PANIC );
- (void) sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC);
-}
-
-const char **get_global_errmsgs()
-{
- return globerrs;
-}
diff --git a/dep/mysqllite/mysys/hash.c b/dep/mysqllite/mysys/hash.c
deleted file mode 100644
index f54ac1a4abb..00000000000
--- a/dep/mysqllite/mysys/hash.c
+++ /dev/null
@@ -1,769 +0,0 @@
-/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 */
-
-/* The hash functions used for saveing keys */
-/* One of key_length or key_length_offset must be given */
-/* Key length of 0 isn't allowed */
-
-#include "mysys_priv.h"
-#include <m_string.h>
-#include <m_ctype.h>
-#include "hash.h"
-
-#define NO_RECORD ((uint) -1)
-#define LOWFIND 1
-#define LOWUSED 2
-#define HIGHFIND 4
-#define HIGHUSED 8
-
-typedef struct st_hash_info {
- uint next; /* index to next key */
- uchar *data; /* data for current entry */
-} HASH_LINK;
-
-static uint my_hash_mask(my_hash_value_type hashnr,
- size_t buffmax, size_t maxlength);
-static void movelink(HASH_LINK *array,uint pos,uint next_link,uint newlink);
-static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key,
- size_t length);
-
-static my_hash_value_type calc_hash(const HASH *hash,
- const uchar *key, size_t length)
-{
- ulong nr1=1, nr2=4;
- hash->charset->coll->hash_sort(hash->charset,(uchar*) key,length,&nr1,&nr2);
- return (my_hash_value_type)nr1;
-}
-
-/**
- @brief Initialize the hash
-
- @details
-
- Initialize the hash, by defining and giving valid values for
- its elements. The failure to allocate memory for the
- hash->array element will not result in a fatal failure. The
- dynamic array that is part of the hash will allocate memory
- as required during insertion.
-
- @param[in,out] hash The hash that is initialized
- @param[in] charset The charater set information
- @param[in] size The hash size
- @param[in] key_offest The key offset for the hash
- @param[in] key_length The length of the key used in
- the hash
- @param[in] get_key get the key for the hash
- @param[in] free_element pointer to the function that
- does cleanup
- @return inidicates success or failure of initialization
- @retval 0 success
- @retval 1 failure
-*/
-my_bool
-_my_hash_init(HASH *hash, uint growth_size, CHARSET_INFO *charset,
- ulong size, size_t key_offset, size_t key_length,
- my_hash_get_key get_key,
- void (*free_element)(void*), uint flags)
-{
- DBUG_ENTER("my_hash_init");
- DBUG_PRINT("enter",("hash: 0x%lx size: %u", (long) hash, (uint) size));
-
- hash->records=0;
- hash->key_offset=key_offset;
- hash->key_length=key_length;
- hash->blength=1;
- hash->get_key=get_key;
- hash->free=free_element;
- hash->flags=flags;
- hash->charset=charset;
- DBUG_RETURN(my_init_dynamic_array_ci(&hash->array,
- sizeof(HASH_LINK), size, growth_size));
-}
-
-
-/*
- Call hash->free on all elements in hash.
-
- SYNOPSIS
- my_hash_free_elements()
- hash hash table
-
- NOTES:
- Sets records to 0
-*/
-
-static inline void my_hash_free_elements(HASH *hash)
-{
- if (hash->free)
- {
- HASH_LINK *data=dynamic_element(&hash->array,0,HASH_LINK*);
- HASH_LINK *end= data + hash->records;
- while (data < end)
- (*hash->free)((data++)->data);
- }
- hash->records=0;
-}
-
-
-/*
- Free memory used by hash.
-
- SYNOPSIS
- my_hash_free()
- hash the hash to delete elements of
-
- NOTES: Hash can't be reused without calling my_hash_init again.
-*/
-
-void my_hash_free(HASH *hash)
-{
- DBUG_ENTER("my_hash_free");
- DBUG_PRINT("enter",("hash: 0x%lx", (long) hash));
-
- my_hash_free_elements(hash);
- hash->free= 0;
- delete_dynamic(&hash->array);
- hash->blength= 0;
- DBUG_VOID_RETURN;
-}
-
-
-/*
- Delete all elements from the hash (the hash itself is to be reused).
-
- SYNOPSIS
- my_hash_reset()
- hash the hash to delete elements of
-*/
-
-void my_hash_reset(HASH *hash)
-{
- DBUG_ENTER("my_hash_reset");
- DBUG_PRINT("enter",("hash: 0x%lxd", (long) hash));
-
- my_hash_free_elements(hash);
- reset_dynamic(&hash->array);
- /* Set row pointers so that the hash can be reused at once */
- hash->blength= 1;
- DBUG_VOID_RETURN;
-}
-
-/* some helper functions */
-
-/*
- This function is char* instead of uchar* as HPUX11 compiler can't
- handle inline functions that are not defined as native types
-*/
-
-static inline char*
-my_hash_key(const HASH *hash, const uchar *record, size_t *length,
- my_bool first)
-{
- if (hash->get_key)
- return (char*) (*hash->get_key)(record,length,first);
- *length=hash->key_length;
- return (char*) record+hash->key_offset;
-}
-
- /* Calculate pos according to keys */
-
-static uint my_hash_mask(my_hash_value_type hashnr, size_t buffmax,
- size_t maxlength)
-{
- if ((hashnr & (buffmax-1)) < maxlength) return (hashnr & (buffmax-1));
- return (hashnr & ((buffmax >> 1) -1));
-}
-
-static uint my_hash_rec_mask(const HASH *hash, HASH_LINK *pos,
- size_t buffmax, size_t maxlength)
-{
- size_t length;
- uchar *key= (uchar*) my_hash_key(hash, pos->data, &length, 0);
- return my_hash_mask(calc_hash(hash, key, length), buffmax, maxlength);
-}
-
-
-
-/* for compilers which can not handle inline */
-static
-#if !defined(__USLC__) && !defined(__sgi)
-inline
-#endif
-my_hash_value_type rec_hashnr(HASH *hash,const uchar *record)
-{
- size_t length;
- uchar *key= (uchar*) my_hash_key(hash, record, &length, 0);
- return calc_hash(hash,key,length);
-}
-
-
-uchar* my_hash_search(const HASH *hash, const uchar *key, size_t length)
-{
- HASH_SEARCH_STATE state;
- return my_hash_first(hash, key, length, &state);
-}
-
-uchar* my_hash_search_using_hash_value(const HASH *hash,
- my_hash_value_type hash_value,
- const uchar *key,
- size_t length)
-{
- HASH_SEARCH_STATE state;
- return my_hash_first_from_hash_value(hash, hash_value,
- key, length, &state);
-}
-
-my_hash_value_type my_calc_hash(const HASH *hash,
- const uchar *key, size_t length)
-{
- return calc_hash(hash, key, length ? length : hash->key_length);
-}
-
-
-/*
- Search after a record based on a key
-
- NOTE
- Assigns the number of the found record to HASH_SEARCH_STATE state
-*/
-
-uchar* my_hash_first(const HASH *hash, const uchar *key, size_t length,
- HASH_SEARCH_STATE *current_record)
-{
- uchar *res;
- if (my_hash_inited(hash))
- res= my_hash_first_from_hash_value(hash,
- calc_hash(hash, key, length ? length : hash->key_length),
- key, length, current_record);
- else
- res= 0;
- return res;
-}
-
-
-uchar* my_hash_first_from_hash_value(const HASH *hash,
- my_hash_value_type hash_value,
- const uchar *key,
- size_t length,
- HASH_SEARCH_STATE *current_record)
-{
- HASH_LINK *pos;
- uint flag,idx;
- DBUG_ENTER("my_hash_first_from_hash_value");
-
- flag=1;
- if (hash->records)
- {
- idx= my_hash_mask(hash_value,
- hash->blength, hash->records);
- do
- {
- pos= dynamic_element(&hash->array,idx,HASH_LINK*);
- if (!hashcmp(hash,pos,key,length))
- {
- DBUG_PRINT("exit",("found key at %d",idx));
- *current_record= idx;
- DBUG_RETURN (pos->data);
- }
- if (flag)
- {
- flag=0; /* Reset flag */
- if (my_hash_rec_mask(hash, pos, hash->blength, hash->records) != idx)
- break; /* Wrong link */
- }
- }
- while ((idx=pos->next) != NO_RECORD);
- }
- *current_record= NO_RECORD;
- DBUG_RETURN(0);
-}
-
- /* Get next record with identical key */
- /* Can only be called if previous calls was my_hash_search */
-
-uchar* my_hash_next(const HASH *hash, const uchar *key, size_t length,
- HASH_SEARCH_STATE *current_record)
-{
- HASH_LINK *pos;
- uint idx;
-
- if (*current_record != NO_RECORD)
- {
- HASH_LINK *data=dynamic_element(&hash->array,0,HASH_LINK*);
- for (idx=data[*current_record].next; idx != NO_RECORD ; idx=pos->next)
- {
- pos=data+idx;
- if (!hashcmp(hash,pos,key,length))
- {
- *current_record= idx;
- return pos->data;
- }
- }
- *current_record= NO_RECORD;
- }
- return 0;
-}
-
-
- /* Change link from pos to new_link */
-
-static void movelink(HASH_LINK *array,uint find,uint next_link,uint newlink)
-{
- HASH_LINK *old_link;
- do
- {
- old_link=array+next_link;
- }
- while ((next_link=old_link->next) != find);
- old_link->next= newlink;
- return;
-}
-
-/*
- Compare a key in a record to a whole key. Return 0 if identical
-
- SYNOPSIS
- hashcmp()
- hash hash table
- pos position of hash record to use in comparison
- key key for comparison
- length length of key
-
- NOTES:
- If length is 0, comparison is done using the length of the
- record being compared against.
-
- RETURN
- = 0 key of record == key
- != 0 key of record != key
- */
-
-static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key,
- size_t length)
-{
- size_t rec_keylength;
- uchar *rec_key= (uchar*) my_hash_key(hash, pos->data, &rec_keylength, 1);
- return ((length && length != rec_keylength) ||
- my_strnncoll(hash->charset, (uchar*) rec_key, rec_keylength,
- (uchar*) key, rec_keylength));
-}
-
-
- /* Write a hash-key to the hash-index */
-
-my_bool my_hash_insert(HASH *info, const uchar *record)
-{
- int flag;
- size_t idx,halfbuff,first_index;
- my_hash_value_type hash_nr;
- uchar *UNINIT_VAR(ptr_to_rec),*UNINIT_VAR(ptr_to_rec2);
- HASH_LINK *data,*empty,*UNINIT_VAR(gpos),*UNINIT_VAR(gpos2),*pos;
-
- if (HASH_UNIQUE & info->flags)
- {
- uchar *key= (uchar*) my_hash_key(info, record, &idx, 1);
- if (my_hash_search(info, key, idx))
- return(TRUE); /* Duplicate entry */
- }
-
- flag=0;
- if (!(empty=(HASH_LINK*) alloc_dynamic(&info->array)))
- return(TRUE); /* No more memory */
-
- data=dynamic_element(&info->array,0,HASH_LINK*);
- halfbuff= info->blength >> 1;
-
- idx=first_index=info->records-halfbuff;
- if (idx != info->records) /* If some records */
- {
- do
- {
- pos=data+idx;
- hash_nr=rec_hashnr(info,pos->data);
- if (flag == 0) /* First loop; Check if ok */
- if (my_hash_mask(hash_nr, info->blength, info->records) != first_index)
- break;
- if (!(hash_nr & halfbuff))
- { /* Key will not move */
- if (!(flag & LOWFIND))
- {
- if (flag & HIGHFIND)
- {
- flag=LOWFIND | HIGHFIND;
- /* key shall be moved to the current empty position */
- gpos=empty;
- ptr_to_rec=pos->data;
- empty=pos; /* This place is now free */
- }
- else
- {
- flag=LOWFIND | LOWUSED; /* key isn't changed */
- gpos=pos;
- ptr_to_rec=pos->data;
- }
- }
- else
- {
- if (!(flag & LOWUSED))
- {
- /* Change link of previous LOW-key */
- gpos->data=ptr_to_rec;
- gpos->next= (uint) (pos-data);
- flag= (flag & HIGHFIND) | (LOWFIND | LOWUSED);
- }
- gpos=pos;
- ptr_to_rec=pos->data;
- }
- }
- else
- { /* key will be moved */
- if (!(flag & HIGHFIND))
- {
- flag= (flag & LOWFIND) | HIGHFIND;
- /* key shall be moved to the last (empty) position */
- gpos2 = empty; empty=pos;
- ptr_to_rec2=pos->data;
- }
- else
- {
- if (!(flag & HIGHUSED))
- {
- /* Change link of previous hash-key and save */
- gpos2->data=ptr_to_rec2;
- gpos2->next=(uint) (pos-data);
- flag= (flag & LOWFIND) | (HIGHFIND | HIGHUSED);
- }
- gpos2=pos;
- ptr_to_rec2=pos->data;
- }
- }
- }
- while ((idx=pos->next) != NO_RECORD);
-
- if ((flag & (LOWFIND | LOWUSED)) == LOWFIND)
- {
- gpos->data=ptr_to_rec;
- gpos->next=NO_RECORD;
- }
- if ((flag & (HIGHFIND | HIGHUSED)) == HIGHFIND)
- {
- gpos2->data=ptr_to_rec2;
- gpos2->next=NO_RECORD;
- }
- }
- /* Check if we are at the empty position */
-
- idx= my_hash_mask(rec_hashnr(info, record), info->blength, info->records + 1);
- pos=data+idx;
- if (pos == empty)
- {
- pos->data=(uchar*) record;
- pos->next=NO_RECORD;
- }
- else
- {
- /* Check if more records in same hash-nr family */
- empty[0]=pos[0];
- gpos= data + my_hash_rec_mask(info, pos, info->blength, info->records + 1);
- if (pos == gpos)
- {
- pos->data=(uchar*) record;
- pos->next=(uint) (empty - data);
- }
- else
- {
- pos->data=(uchar*) record;
- pos->next=NO_RECORD;
- movelink(data,(uint) (pos-data),(uint) (gpos-data),(uint) (empty-data));
- }
- }
- if (++info->records == info->blength)
- info->blength+= info->blength;
- return(0);
-}
-
-
-/******************************************************************************
-** Remove one record from hash-table. The record with the same record
-** ptr is removed.
-** if there is a free-function it's called for record if found
-******************************************************************************/
-
-my_bool my_hash_delete(HASH *hash, uchar *record)
-{
- uint blength,pos2,idx,empty_index;
- my_hash_value_type pos_hashnr, lastpos_hashnr;
- HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty;
- DBUG_ENTER("my_hash_delete");
- if (!hash->records)
- DBUG_RETURN(1);
-
- blength=hash->blength;
- data=dynamic_element(&hash->array,0,HASH_LINK*);
- /* Search after record with key */
- pos= data + my_hash_mask(rec_hashnr(hash, record), blength, hash->records);
- gpos = 0;
-
- while (pos->data != record)
- {
- gpos=pos;
- if (pos->next == NO_RECORD)
- DBUG_RETURN(1); /* Key not found */
- pos=data+pos->next;
- }
-
- if ( --(hash->records) < hash->blength >> 1) hash->blength>>=1;
- lastpos=data+hash->records;
-
- /* Remove link to record */
- empty=pos; empty_index=(uint) (empty-data);
- if (gpos)
- gpos->next=pos->next; /* unlink current ptr */
- else if (pos->next != NO_RECORD)
- {
- empty=data+(empty_index=pos->next);
- pos->data=empty->data;
- pos->next=empty->next;
- }
-
- if (empty == lastpos) /* last key at wrong pos or no next link */
- goto exit;
-
- /* Move the last key (lastpos) */
- lastpos_hashnr=rec_hashnr(hash,lastpos->data);
- /* pos is where lastpos should be */
- pos= data + my_hash_mask(lastpos_hashnr, hash->blength, hash->records);
- if (pos == empty) /* Move to empty position. */
- {
- empty[0]=lastpos[0];
- goto exit;
- }
- pos_hashnr=rec_hashnr(hash,pos->data);
- /* pos3 is where the pos should be */
- pos3= data + my_hash_mask(pos_hashnr, hash->blength, hash->records);
- if (pos != pos3)
- { /* pos is on wrong posit */
- empty[0]=pos[0]; /* Save it here */
- pos[0]=lastpos[0]; /* This should be here */
- movelink(data,(uint) (pos-data),(uint) (pos3-data),empty_index);
- goto exit;
- }
- pos2= my_hash_mask(lastpos_hashnr, blength, hash->records + 1);
- if (pos2 == my_hash_mask(pos_hashnr, blength, hash->records + 1))
- { /* Identical key-positions */
- if (pos2 != hash->records)
- {
- empty[0]=lastpos[0];
- movelink(data,(uint) (lastpos-data),(uint) (pos-data),empty_index);
- goto exit;
- }
- idx= (uint) (pos-data); /* Link pos->next after lastpos */
- }
- else idx= NO_RECORD; /* Different positions merge */
-
- empty[0]=lastpos[0];
- movelink(data,idx,empty_index,pos->next);
- pos->next=empty_index;
-
-exit:
- (void) pop_dynamic(&hash->array);
- if (hash->free)
- (*hash->free)((uchar*) record);
- DBUG_RETURN(0);
-}
-
- /*
- Update keys when record has changed.
- This is much more efficent than using a delete & insert.
- */
-
-my_bool my_hash_update(HASH *hash, uchar *record, uchar *old_key,
- size_t old_key_length)
-{
- uint new_index,new_pos_index,blength,records;
- size_t idx,empty;
- HASH_LINK org_link,*data,*previous,*pos;
- DBUG_ENTER("my_hash_update");
-
- if (HASH_UNIQUE & hash->flags)
- {
- HASH_SEARCH_STATE state;
- uchar *found, *new_key= (uchar*) my_hash_key(hash, record, &idx, 1);
- if ((found= my_hash_first(hash, new_key, idx, &state)))
- {
- do
- {
- if (found != record)
- DBUG_RETURN(1); /* Duplicate entry */
- }
- while ((found= my_hash_next(hash, new_key, idx, &state)));
- }
- }
-
- data=dynamic_element(&hash->array,0,HASH_LINK*);
- blength=hash->blength; records=hash->records;
-
- /* Search after record with key */
-
- idx= my_hash_mask(calc_hash(hash, old_key, (old_key_length ?
- old_key_length :
- hash->key_length)),
- blength, records);
- new_index= my_hash_mask(rec_hashnr(hash, record), blength, records);
- if (idx == new_index)
- DBUG_RETURN(0); /* Nothing to do (No record check) */
- previous=0;
- for (;;)
- {
-
- if ((pos= data+idx)->data == record)
- break;
- previous=pos;
- if ((idx=pos->next) == NO_RECORD)
- DBUG_RETURN(1); /* Not found in links */
- }
- org_link= *pos;
- empty=idx;
-
- /* Relink record from current chain */
-
- if (!previous)
- {
- if (pos->next != NO_RECORD)
- {
- empty=pos->next;
- *pos= data[pos->next];
- }
- }
- else
- previous->next=pos->next; /* unlink pos */
-
- /* Move data to correct position */
- if (new_index == empty)
- {
- /*
- At this point record is unlinked from the old chain, thus it holds
- random position. By the chance this position is equal to position
- for the first element in the new chain. That means updated record
- is the only record in the new chain.
- */
- if (empty != idx)
- {
- /*
- Record was moved while unlinking it from the old chain.
- Copy data to a new position.
- */
- data[empty]= org_link;
- }
- data[empty].next= NO_RECORD;
- DBUG_RETURN(0);
- }
- pos=data+new_index;
- new_pos_index= my_hash_rec_mask(hash, pos, blength, records);
- if (new_index != new_pos_index)
- { /* Other record in wrong position */
- data[empty] = *pos;
- movelink(data,new_index,new_pos_index,empty);
- org_link.next=NO_RECORD;
- data[new_index]= org_link;
- }
- else
- { /* Link in chain at right position */
- org_link.next=data[new_index].next;
- data[empty]=org_link;
- data[new_index].next=empty;
- }
- DBUG_RETURN(0);
-}
-
-
-uchar *my_hash_element(HASH *hash, ulong idx)
-{
- if (idx < hash->records)
- return dynamic_element(&hash->array,idx,HASH_LINK*)->data;
- return 0;
-}
-
-
-/*
- Replace old row with new row. This should only be used when key
- isn't changed
-*/
-
-void my_hash_replace(HASH *hash, HASH_SEARCH_STATE *current_record,
- uchar *new_row)
-{
- if (*current_record != NO_RECORD) /* Safety */
- dynamic_element(&hash->array, *current_record, HASH_LINK*)->data= new_row;
-}
-
-
-#ifndef DBUG_OFF
-
-my_bool my_hash_check(HASH *hash)
-{
- int error;
- uint i,rec_link,found,max_links,seek,links,idx;
- uint records,blength;
- HASH_LINK *data,*hash_info;
-
- records=hash->records; blength=hash->blength;
- data=dynamic_element(&hash->array,0,HASH_LINK*);
- error=0;
-
- for (i=found=max_links=seek=0 ; i < records ; i++)
- {
- if (my_hash_rec_mask(hash, data + i, blength, records) == i)
- {
- found++; seek++; links=1;
- for (idx=data[i].next ;
- idx != NO_RECORD && found < records + 1;
- idx=hash_info->next)
- {
- if (idx >= records)
- {
- DBUG_PRINT("error",
- ("Found pointer outside array to %d from link starting at %d",
- idx,i));
- error=1;
- }
- hash_info=data+idx;
- seek+= ++links;
- if ((rec_link= my_hash_rec_mask(hash, hash_info,
- blength, records)) != i)
- {
- DBUG_PRINT("error", ("Record in wrong link at %d: Start %d "
- "Record: 0x%lx Record-link %d",
- idx, i, (long) hash_info->data, rec_link));
- error=1;
- }
- else
- found++;
- }
- if (links > max_links) max_links=links;
- }
- }
- if (found != records)
- {
- DBUG_PRINT("error",("Found %u of %u records", found, records));
- error=1;
- }
- if (records)
- DBUG_PRINT("info",
- ("records: %u seeks: %d max links: %d hitrate: %.2f",
- records,seek,max_links,(float) seek / (float) records));
- return error;
-}
-#endif
diff --git a/dep/mysqllite/mysys/lf_alloc-pin.c b/dep/mysqllite/mysys/lf_alloc-pin.c
deleted file mode 100644
index 4ed01ac8083..00000000000
--- a/dep/mysqllite/mysys/lf_alloc-pin.c
+++ /dev/null
@@ -1,527 +0,0 @@
-/* QQ: TODO multi-pinbox */
-/* Copyright (C) 2006-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 */
-
-/*
- wait-free concurrent allocator based on pinning addresses
-
- It works as follows: every thread (strictly speaking - every CPU, but
- it's too difficult to do) has a small array of pointers. They're called
- "pins". Before using an object its address must be stored in this array
- (pinned). When an object is no longer necessary its address must be
- removed from this array (unpinned). When a thread wants to free() an
- object it scans all pins of all threads to see if somebody has this
- object pinned. If yes - the object is not freed (but stored in a
- "purgatory"). To reduce the cost of a single free() pins are not scanned
- on every free() but only added to (thread-local) purgatory. On every
- LF_PURGATORY_SIZE free() purgatory is scanned and all unpinned objects
- are freed.
-
- Pins are used to solve ABA problem. To use pins one must obey
- a pinning protocol:
-
- 1. Let's assume that PTR is a shared pointer to an object. Shared means
- that any thread may modify it anytime to point to a different object
- and free the old object. Later the freed object may be potentially
- allocated by another thread. If we're unlucky that other thread may
- set PTR to point to this object again. This is ABA problem.
- 2. Create a local pointer LOCAL_PTR.
- 3. Pin the PTR in a loop:
- do
- {
- LOCAL_PTR= PTR;
- pin(PTR, PIN_NUMBER);
- } while (LOCAL_PTR != PTR)
- 4. It is guaranteed that after the loop has ended, LOCAL_PTR
- points to an object (or NULL, if PTR may be NULL), that
- will never be freed. It is not guaranteed though
- that LOCAL_PTR == PTR (as PTR can change any time)
- 5. When done working with the object, remove the pin:
- unpin(PIN_NUMBER)
- 6. When copying pins (as in the list traversing loop:
- pin(CUR, 1);
- while ()
- {
- do // standard
- { // pinning
- NEXT=CUR->next; // loop
- pin(NEXT, 0); // see #3
- } while (NEXT != CUR->next); // above
- ...
- ...
- CUR=NEXT;
- pin(CUR, 1); // copy pin[0] to pin[1]
- }
- which keeps CUR address constantly pinned), note than pins may be
- copied only upwards (!!!), that is pin[N] to pin[M], M > N.
- 7. Don't keep the object pinned longer than necessary - the number of
- pins you have is limited (and small), keeping an object pinned
- prevents its reuse and cause unnecessary mallocs.
-
- Explanations:
-
- 3. The loop is important. The following can occur:
- thread1> LOCAL_PTR= PTR
- thread2> free(PTR); PTR=0;
- thread1> pin(PTR, PIN_NUMBER);
- now thread1 cannot access LOCAL_PTR, even if it's pinned,
- because it points to a freed memory. That is, it *must*
- verify that it has indeed pinned PTR, the shared pointer.
-
- 6. When a thread wants to free some LOCAL_PTR, and it scans
- all lists of pins to see whether it's pinned, it does it
- upwards, from low pin numbers to high. Thus another thread
- must copy an address from one pin to another in the same
- direction - upwards, otherwise the scanning thread may
- miss it.
-
- Implementation details:
-
- Pins are given away from a "pinbox". Pinbox is stack-based allocator.
- It used dynarray for storing pins, new elements are allocated by dynarray
- as necessary, old are pushed in the stack for reuse. ABA is solved by
- versioning a pointer - because we use an array, a pointer to pins is 16 bit,
- upper 16 bits are used for a version.
-
- It is assumed that pins belong to a THD and are not transferable
- between THD's (LF_PINS::stack_ends_here being a primary reason
- for this limitation).
-*/
-#include <my_global.h>
-#include <my_sys.h>
-#include <lf.h>
-
-#define LF_PINBOX_MAX_PINS 65536
-
-static void _lf_pinbox_real_free(LF_PINS *pins);
-
-/*
- Initialize a pinbox. Normally called from lf_alloc_init.
- See the latter for details.
-*/
-void lf_pinbox_init(LF_PINBOX *pinbox, uint free_ptr_offset,
- lf_pinbox_free_func *free_func, void *free_func_arg)
-{
- DBUG_ASSERT(free_ptr_offset % sizeof(void *) == 0);
- compile_time_assert(sizeof(LF_PINS) == 64);
- lf_dynarray_init(&pinbox->pinarray, sizeof(LF_PINS));
- pinbox->pinstack_top_ver= 0;
- pinbox->pins_in_array= 0;
- pinbox->free_ptr_offset= free_ptr_offset;
- pinbox->free_func= free_func;
- pinbox->free_func_arg= free_func_arg;
-}
-
-void lf_pinbox_destroy(LF_PINBOX *pinbox)
-{
- lf_dynarray_destroy(&pinbox->pinarray);
-}
-
-/*
- Get pins from a pinbox. Usually called via lf_alloc_get_pins() or
- lf_hash_get_pins().
-
- SYNOPSYS
- pinbox -
-
- DESCRIPTION
- get a new LF_PINS structure from a stack of unused pins,
- or allocate a new one out of dynarray.
-
- NOTE
- It is assumed that pins belong to a thread and are not transferable
- between threads.
-*/
-LF_PINS *_lf_pinbox_get_pins(LF_PINBOX *pinbox)
-{
- uint32 pins, next, top_ver;
- LF_PINS *el;
- /*
- We have an array of max. 64k elements.
- The highest index currently allocated is pinbox->pins_in_array.
- Freed elements are in a lifo stack, pinstack_top_ver.
- pinstack_top_ver is 32 bits; 16 low bits are the index in the
- array, to the first element of the list. 16 high bits are a version
- (every time the 16 low bits are updated, the 16 high bits are
- incremented). Versioniong prevents the ABA problem.
- */
- top_ver= pinbox->pinstack_top_ver;
- do
- {
- if (!(pins= top_ver % LF_PINBOX_MAX_PINS))
- {
- /* the stack of free elements is empty */
- pins= my_atomic_add32((int32 volatile*) &pinbox->pins_in_array, 1)+1;
- if (unlikely(pins >= LF_PINBOX_MAX_PINS))
- return 0;
- /*
- note that the first allocated element has index 1 (pins==1).
- index 0 is reserved to mean "NULL pointer"
- */
- el= (LF_PINS *)_lf_dynarray_lvalue(&pinbox->pinarray, pins);
- if (unlikely(!el))
- return 0;
- break;
- }
- el= (LF_PINS *)_lf_dynarray_value(&pinbox->pinarray, pins);
- next= el->link;
- } while (!my_atomic_cas32((int32 volatile*) &pinbox->pinstack_top_ver,
- (int32*) &top_ver,
- top_ver-pins+next+LF_PINBOX_MAX_PINS));
- /*
- set el->link to the index of el in the dynarray (el->link has two usages:
- - if element is allocated, it's its own index
- - if element is free, it's its next element in the free stack
- */
- el->link= pins;
- el->purgatory_count= 0;
- el->pinbox= pinbox;
- el->stack_ends_here= & my_thread_var->stack_ends_here;
- return el;
-}
-
-/*
- Put pins back to a pinbox. Usually called via lf_alloc_put_pins() or
- lf_hash_put_pins().
-
- DESCRIPTION
- empty the purgatory (XXX deadlock warning below!),
- push LF_PINS structure to a stack
-*/
-void _lf_pinbox_put_pins(LF_PINS *pins)
-{
- LF_PINBOX *pinbox= pins->pinbox;
- uint32 top_ver, nr;
- nr= pins->link;
-#ifdef MY_LF_EXTRA_DEBUG
- {
- int i;
- for (i= 0; i < LF_PINBOX_PINS; i++)
- DBUG_ASSERT(pins->pin[i] == 0);
- }
-#endif
- /*
- XXX this will deadlock if other threads will wait for
- the caller to do something after _lf_pinbox_put_pins(),
- and they would have pinned addresses that the caller wants to free.
- Thus: only free pins when all work is done and nobody can wait for you!!!
- */
- while (pins->purgatory_count)
- {
- _lf_pinbox_real_free(pins);
- if (pins->purgatory_count)
- {
- my_atomic_rwlock_wrunlock(&pins->pinbox->pinarray.lock);
- pthread_yield();
- my_atomic_rwlock_wrlock(&pins->pinbox->pinarray.lock);
- }
- }
- top_ver= pinbox->pinstack_top_ver;
- do
- {
- pins->link= top_ver % LF_PINBOX_MAX_PINS;
- } while (!my_atomic_cas32((int32 volatile*) &pinbox->pinstack_top_ver,
- (int32*) &top_ver,
- top_ver-pins->link+nr+LF_PINBOX_MAX_PINS));
- return;
-}
-
-static int ptr_cmp(void **a, void **b)
-{
- return *a < *b ? -1 : *a == *b ? 0 : 1;
-}
-
-#define add_to_purgatory(PINS, ADDR) \
- do \
- { \
- *(void **)((char *)(ADDR)+(PINS)->pinbox->free_ptr_offset)= \
- (PINS)->purgatory; \
- (PINS)->purgatory= (ADDR); \
- (PINS)->purgatory_count++; \
- } while (0)
-
-/*
- Free an object allocated via pinbox allocator
-
- DESCRIPTION
- add an object to purgatory. if necessary, call _lf_pinbox_real_free()
- to actually free something.
-*/
-void _lf_pinbox_free(LF_PINS *pins, void *addr)
-{
- add_to_purgatory(pins, addr);
- if (pins->purgatory_count % LF_PURGATORY_SIZE)
- _lf_pinbox_real_free(pins);
-}
-
-struct st_harvester {
- void **granary;
- int npins;
-};
-
-/*
- callback for _lf_dynarray_iterate:
- scan all pins of all threads and accumulate all pins
-*/
-static int harvest_pins(LF_PINS *el, struct st_harvester *hv)
-{
- int i;
- LF_PINS *el_end= el+min(hv->npins, LF_DYNARRAY_LEVEL_LENGTH);
- for (; el < el_end; el++)
- {
- for (i= 0; i < LF_PINBOX_PINS; i++)
- {
- void *p= el->pin[i];
- if (p)
- *hv->granary++= p;
- }
- }
- /*
- hv->npins may become negative below, but it means that
- we're on the last dynarray page and harvest_pins() won't be
- called again. We don't bother to make hv->npins() correct
- (that is 0) in this case.
- */
- hv->npins-= LF_DYNARRAY_LEVEL_LENGTH;
- return 0;
-}
-
-/*
- callback for _lf_dynarray_iterate:
- scan all pins of all threads and see if addr is present there
-*/
-static int match_pins(LF_PINS *el, void *addr)
-{
- int i;
- LF_PINS *el_end= el+LF_DYNARRAY_LEVEL_LENGTH;
- for (; el < el_end; el++)
- for (i= 0; i < LF_PINBOX_PINS; i++)
- if (el->pin[i] == addr)
- return 1;
- return 0;
-}
-
-#if STACK_DIRECTION < 0
-#define available_stack_size(CUR,END) (long) ((char*)(CUR) - (char*)(END))
-#else
-#define available_stack_size(CUR,END) (long) ((char*)(END) - (char*)(CUR))
-#endif
-
-#define next_node(P, X) (*((uchar * volatile *)(((uchar *)(X)) + (P)->free_ptr_offset)))
-#define anext_node(X) next_node(&allocator->pinbox, (X))
-
-/*
- Scan the purgatory and free everything that can be freed
-*/
-static void _lf_pinbox_real_free(LF_PINS *pins)
-{
- int npins, alloca_size;
- void *list, **addr;
- void *first= NULL, *last= NULL;
- LF_PINBOX *pinbox= pins->pinbox;
-
- npins= pinbox->pins_in_array+1;
-
-#ifdef HAVE_ALLOCA
- alloca_size= sizeof(void *)*LF_PINBOX_PINS*npins;
- /* create a sorted list of pinned addresses, to speed up searches */
- if (available_stack_size(&pinbox, *pins->stack_ends_here) > alloca_size)
- {
- struct st_harvester hv;
- addr= (void **) alloca(alloca_size);
- hv.granary= addr;
- hv.npins= npins;
- /* scan the dynarray and accumulate all pinned addresses */
- _lf_dynarray_iterate(&pinbox->pinarray,
- (lf_dynarray_func)harvest_pins, &hv);
-
- npins= hv.granary-addr;
- /* and sort them */
- if (npins)
- qsort(addr, npins, sizeof(void *), (qsort_cmp)ptr_cmp);
- }
- else
-#endif
- addr= 0;
-
- list= pins->purgatory;
- pins->purgatory= 0;
- pins->purgatory_count= 0;
- while (list)
- {
- void *cur= list;
- list= *(void **)((char *)cur+pinbox->free_ptr_offset);
- if (npins)
- {
- if (addr) /* use binary search */
- {
- void **a, **b, **c;
- for (a= addr, b= addr+npins-1, c= a+(b-a)/2; (b-a) > 1; c= a+(b-a)/2)
- if (cur == *c)
- a= b= c;
- else if (cur > *c)
- a= c;
- else
- b= c;
- if (cur == *a || cur == *b)
- goto found;
- }
- else /* no alloca - no cookie. linear search here */
- {
- if (_lf_dynarray_iterate(&pinbox->pinarray,
- (lf_dynarray_func)match_pins, cur))
- goto found;
- }
- }
- /* not pinned - freeing */
- if (last)
- last= next_node(pinbox, last)= (uchar *)cur;
- else
- first= last= (uchar *)cur;
- continue;
-found:
- /* pinned - keeping */
- add_to_purgatory(pins, cur);
- }
- if (last)
- pinbox->free_func(first, last, pinbox->free_func_arg);
-}
-
-/* lock-free memory allocator for fixed-size objects */
-
-LF_REQUIRE_PINS(1)
-
-/*
- callback for _lf_pinbox_real_free to free a list of unpinned objects -
- add it back to the allocator stack
-
- DESCRIPTION
- 'first' and 'last' are the ends of the linked list of nodes:
- first->el->el->....->el->last. Use first==last to free only one element.
-*/
-static void alloc_free(uchar *first,
- uchar volatile *last,
- LF_ALLOCATOR *allocator)
-{
- /*
- we need a union here to access type-punned pointer reliably.
- otherwise gcc -fstrict-aliasing will not see 'tmp' changed in the loop
- */
- union { uchar * node; void *ptr; } tmp;
- tmp.node= allocator->top;
- do
- {
- anext_node(last)= tmp.node;
- } while (!my_atomic_casptr((void **)(char *)&allocator->top,
- (void **)&tmp.ptr, first) && LF_BACKOFF);
-}
-
-/*
- initialize lock-free allocator
-
- SYNOPSYS
- allocator -
- size a size of an object to allocate
- free_ptr_offset an offset inside the object to a sizeof(void *)
- memory that is guaranteed to be unused after
- the object is put in the purgatory. Unused by ANY
- thread, not only the purgatory owner.
- This memory will be used to link waiting-to-be-freed
- objects in a purgatory list.
-*/
-void lf_alloc_init(LF_ALLOCATOR *allocator, uint size, uint free_ptr_offset)
-{
- lf_pinbox_init(&allocator->pinbox, free_ptr_offset,
- (lf_pinbox_free_func *)alloc_free, allocator);
- allocator->top= 0;
- allocator->mallocs= 0;
- allocator->element_size= size;
- DBUG_ASSERT(size >= sizeof(void*) + free_ptr_offset);
-}
-
-/*
- destroy the allocator, free everything that's in it
-
- NOTE
- As every other init/destroy function here and elsewhere it
- is not thread safe. No, this function is no different, ensure
- that no thread needs the allocator before destroying it.
- We are not responsible for any damage that may be caused by
- accessing the allocator when it is being or has been destroyed.
- Oh yes, and don't put your cat in a microwave.
-*/
-void lf_alloc_destroy(LF_ALLOCATOR *allocator)
-{
- uchar *node= allocator->top;
- while (node)
- {
- uchar *tmp= anext_node(node);
- my_free(node);
- node= tmp;
- }
- lf_pinbox_destroy(&allocator->pinbox);
- allocator->top= 0;
-}
-
-/*
- Allocate and return an new object.
-
- DESCRIPTION
- Pop an unused object from the stack or malloc it is the stack is empty.
- pin[0] is used, it's removed on return.
-*/
-void *_lf_alloc_new(LF_PINS *pins)
-{
- LF_ALLOCATOR *allocator= (LF_ALLOCATOR *)(pins->pinbox->free_func_arg);
- uchar *node;
- for (;;)
- {
- do
- {
- node= allocator->top;
- _lf_pin(pins, 0, node);
- } while (node != allocator->top && LF_BACKOFF);
- if (!node)
- {
- node= (void *)my_malloc(allocator->element_size, MYF(MY_WME));
-#ifdef MY_LF_EXTRA_DEBUG
- if (likely(node != 0))
- my_atomic_add32(&allocator->mallocs, 1);
-#endif
- break;
- }
- if (my_atomic_casptr((void **)(char *)&allocator->top,
- (void *)&node, anext_node(node)))
- break;
- }
- _lf_unpin(pins, 0);
- return node;
-}
-
-/*
- count the number of objects in a pool.
-
- NOTE
- This is NOT thread-safe !!!
-*/
-uint lf_alloc_pool_count(LF_ALLOCATOR *allocator)
-{
- uint i;
- uchar *node;
- for (node= allocator->top, i= 0; node; node= anext_node(node), i++)
- /* no op */;
- return i;
-}
-
diff --git a/dep/mysqllite/mysys/lf_dynarray.c b/dep/mysqllite/mysys/lf_dynarray.c
deleted file mode 100644
index 0941c8762bb..00000000000
--- a/dep/mysqllite/mysys/lf_dynarray.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/* 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 */
-
-/*
- Analog of DYNAMIC_ARRAY that never reallocs
- (so no pointer into the array may ever become invalid).
-
- Memory is allocated in non-contiguous chunks.
- This data structure is not space efficient for sparse arrays.
-
- Every element is aligned to sizeof(element) boundary
- (to avoid false sharing if element is big enough).
-
- LF_DYNARRAY is a recursive structure. On the zero level
- LF_DYNARRAY::level[0] it's an array of LF_DYNARRAY_LEVEL_LENGTH elements,
- on the first level it's an array of LF_DYNARRAY_LEVEL_LENGTH pointers
- to arrays of elements, on the second level it's an array of pointers
- to arrays of pointers to arrays of elements. And so on.
-
- With four levels the number of elements is limited to 4311810304
- (but as in all functions index is uint, the real limit is 2^32-1)
-
- Actually, it's wait-free, not lock-free ;-)
-*/
-
-#include <my_global.h>
-#include <m_string.h>
-#include <my_sys.h>
-#include <lf.h>
-
-void lf_dynarray_init(LF_DYNARRAY *array, uint element_size)
-{
- bzero(array, sizeof(*array));
- array->size_of_element= element_size;
- my_atomic_rwlock_init(&array->lock);
-}
-
-static void recursive_free(void **alloc, int level)
-{
- if (!alloc)
- return;
-
- if (level)
- {
- int i;
- for (i= 0; i < LF_DYNARRAY_LEVEL_LENGTH; i++)
- recursive_free(alloc[i], level-1);
- my_free(alloc);
- }
- else
- my_free(alloc[-1]);
-}
-
-void lf_dynarray_destroy(LF_DYNARRAY *array)
-{
- int i;
- for (i= 0; i < LF_DYNARRAY_LEVELS; i++)
- recursive_free(array->level[i], i);
- my_atomic_rwlock_destroy(&array->lock);
-}
-
-static const ulong dynarray_idxes_in_prev_levels[LF_DYNARRAY_LEVELS]=
-{
- 0, /* +1 here to to avoid -1's below */
- LF_DYNARRAY_LEVEL_LENGTH,
- LF_DYNARRAY_LEVEL_LENGTH * LF_DYNARRAY_LEVEL_LENGTH +
- LF_DYNARRAY_LEVEL_LENGTH,
- LF_DYNARRAY_LEVEL_LENGTH * LF_DYNARRAY_LEVEL_LENGTH *
- LF_DYNARRAY_LEVEL_LENGTH + LF_DYNARRAY_LEVEL_LENGTH *
- LF_DYNARRAY_LEVEL_LENGTH + LF_DYNARRAY_LEVEL_LENGTH
-};
-
-static const ulong dynarray_idxes_in_prev_level[LF_DYNARRAY_LEVELS]=
-{
- 0, /* +1 here to to avoid -1's below */
- LF_DYNARRAY_LEVEL_LENGTH,
- LF_DYNARRAY_LEVEL_LENGTH * LF_DYNARRAY_LEVEL_LENGTH,
- LF_DYNARRAY_LEVEL_LENGTH * LF_DYNARRAY_LEVEL_LENGTH *
- LF_DYNARRAY_LEVEL_LENGTH,
-};
-
-/*
- Returns a valid lvalue pointer to the element number 'idx'.
- Allocates memory if necessary.
-*/
-void *_lf_dynarray_lvalue(LF_DYNARRAY *array, uint idx)
-{
- void * ptr, * volatile * ptr_ptr= 0;
- int i;
-
- for (i= LF_DYNARRAY_LEVELS-1; idx < dynarray_idxes_in_prev_levels[i]; i--)
- /* no-op */;
- ptr_ptr= &array->level[i];
- idx-= dynarray_idxes_in_prev_levels[i];
- for (; i > 0; i--)
- {
- if (!(ptr= *ptr_ptr))
- {
- void *alloc= my_malloc(LF_DYNARRAY_LEVEL_LENGTH * sizeof(void *),
- MYF(MY_WME|MY_ZEROFILL));
- if (unlikely(!alloc))
- return(NULL);
- if (my_atomic_casptr(ptr_ptr, &ptr, alloc))
- ptr= alloc;
- else
- my_free(alloc);
- }
- ptr_ptr= ((void **)ptr) + idx / dynarray_idxes_in_prev_level[i];
- idx%= dynarray_idxes_in_prev_level[i];
- }
- if (!(ptr= *ptr_ptr))
- {
- uchar *alloc, *data;
- alloc= my_malloc(LF_DYNARRAY_LEVEL_LENGTH * array->size_of_element +
- max(array->size_of_element, sizeof(void *)),
- MYF(MY_WME|MY_ZEROFILL));
- if (unlikely(!alloc))
- return(NULL);
- /* reserve the space for free() address */
- data= alloc + sizeof(void *);
- { /* alignment */
- intptr mod= ((intptr)data) % array->size_of_element;
- if (mod)
- data+= array->size_of_element - mod;
- }
- ((void **)data)[-1]= alloc; /* free() will need the original pointer */
- if (my_atomic_casptr(ptr_ptr, &ptr, data))
- ptr= data;
- else
- my_free(alloc);
- }
- return ((uchar*)ptr) + array->size_of_element * idx;
-}
-
-/*
- Returns a pointer to the element number 'idx'
- or NULL if an element does not exists
-*/
-void *_lf_dynarray_value(LF_DYNARRAY *array, uint idx)
-{
- void * ptr, * volatile * ptr_ptr= 0;
- int i;
-
- for (i= LF_DYNARRAY_LEVELS-1; idx < dynarray_idxes_in_prev_levels[i]; i--)
- /* no-op */;
- ptr_ptr= &array->level[i];
- idx-= dynarray_idxes_in_prev_levels[i];
- for (; i > 0; i--)
- {
- if (!(ptr= *ptr_ptr))
- return(NULL);
- ptr_ptr= ((void **)ptr) + idx / dynarray_idxes_in_prev_level[i];
- idx %= dynarray_idxes_in_prev_level[i];
- }
- if (!(ptr= *ptr_ptr))
- return(NULL);
- return ((uchar*)ptr) + array->size_of_element * idx;
-}
-
-static int recursive_iterate(LF_DYNARRAY *array, void *ptr, int level,
- lf_dynarray_func func, void *arg)
-{
- int res, i;
- if (!ptr)
- return 0;
- if (!level)
- return func(ptr, arg);
- for (i= 0; i < LF_DYNARRAY_LEVEL_LENGTH; i++)
- if ((res= recursive_iterate(array, ((void **)ptr)[i], level-1, func, arg)))
- return res;
- return 0;
-}
-
-/*
- Calls func(array, arg) on every array of LF_DYNARRAY_LEVEL_LENGTH elements
- in lf_dynarray.
-
- DESCRIPTION
- lf_dynarray consists of a set of arrays, LF_DYNARRAY_LEVEL_LENGTH elements
- each. _lf_dynarray_iterate() calls user-supplied function on every array
- from the set. It is the fastest way to scan the array, faster than
- for (i=0; i < N; i++) { func(_lf_dynarray_value(dynarray, i)); }
-
- NOTE
- if func() returns non-zero, the scan is aborted
-*/
-int _lf_dynarray_iterate(LF_DYNARRAY *array, lf_dynarray_func func, void *arg)
-{
- int i, res;
- for (i= 0; i < LF_DYNARRAY_LEVELS; i++)
- if ((res= recursive_iterate(array, array->level[i], i, func, arg)))
- return res;
- return 0;
-}
-
diff --git a/dep/mysqllite/mysys/lf_hash.c b/dep/mysqllite/mysys/lf_hash.c
deleted file mode 100644
index e7bf82fc6ca..00000000000
--- a/dep/mysqllite/mysys/lf_hash.c
+++ /dev/null
@@ -1,503 +0,0 @@
-/* Copyright (C) 2006-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 */
-
-/*
- extensible hash
-
- TODO
- try to get rid of dummy nodes ?
- for non-unique hash, count only _distinct_ values
- (but how to do it in lf_hash_delete ?)
-*/
-#include <my_global.h>
-#include <m_string.h>
-#include <my_sys.h>
-#include <my_bit.h>
-#include <lf.h>
-
-LF_REQUIRE_PINS(3)
-
-/* An element of the list */
-typedef struct {
- intptr volatile link; /* a pointer to the next element in a listand a flag */
- uint32 hashnr; /* reversed hash number, for sorting */
- const uchar *key;
- size_t keylen;
- /*
- data is stored here, directly after the keylen.
- thus the pointer to data is (void*)(slist_element_ptr+1)
- */
-} LF_SLIST;
-
-/*
- a structure to pass the context (pointers two the three successive elements
- in a list) from lfind to linsert/ldelete
-*/
-typedef struct {
- intptr volatile *prev;
- LF_SLIST *curr, *next;
-} CURSOR;
-
-/*
- the last bit in LF_SLIST::link is a "deleted" flag.
- the helper macros below convert it to a pure pointer or a pure flag
-*/
-#define PTR(V) (LF_SLIST *)((V) & (~(intptr)1))
-#define DELETED(V) ((V) & 1)
-
-/*
- DESCRIPTION
- Search for hashnr/key/keylen in the list starting from 'head' and
- position the cursor. The list is ORDER BY hashnr, key
-
- RETURN
- 0 - not found
- 1 - found
-
- NOTE
- cursor is positioned in either case
- pins[0..2] are used, they are NOT removed on return
-*/
-static int lfind(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr,
- const uchar *key, uint keylen, CURSOR *cursor, LF_PINS *pins)
-{
- uint32 cur_hashnr;
- const uchar *cur_key;
- uint cur_keylen;
- intptr link;
-
-retry:
- cursor->prev= (intptr *)head;
- do { /* PTR() isn't necessary below, head is a dummy node */
- cursor->curr= (LF_SLIST *)(*cursor->prev);
- _lf_pin(pins, 1, cursor->curr);
- } while (*cursor->prev != (intptr)cursor->curr && LF_BACKOFF);
- for (;;)
- {
- if (unlikely(!cursor->curr))
- return 0; /* end of the list */
- do {
- /* QQ: XXX or goto retry ? */
- link= cursor->curr->link;
- cursor->next= PTR(link);
- _lf_pin(pins, 0, cursor->next);
- } while (link != cursor->curr->link && LF_BACKOFF);
- cur_hashnr= cursor->curr->hashnr;
- cur_key= cursor->curr->key;
- cur_keylen= cursor->curr->keylen;
- if (*cursor->prev != (intptr)cursor->curr)
- {
- (void)LF_BACKOFF;
- goto retry;
- }
- if (!DELETED(link))
- {
- if (cur_hashnr >= hashnr)
- {
- int r= 1;
- if (cur_hashnr > hashnr ||
- (r= my_strnncoll(cs, (uchar*) cur_key, cur_keylen, (uchar*) key,
- keylen)) >= 0)
- return !r;
- }
- cursor->prev= &(cursor->curr->link);
- _lf_pin(pins, 2, cursor->curr);
- }
- else
- {
- /*
- we found a deleted node - be nice, help the other thread
- and remove this deleted node
- */
- if (my_atomic_casptr((void **)cursor->prev,
- (void **)&cursor->curr, cursor->next))
- _lf_alloc_free(pins, cursor->curr);
- else
- {
- (void)LF_BACKOFF;
- goto retry;
- }
- }
- cursor->curr= cursor->next;
- _lf_pin(pins, 1, cursor->curr);
- }
-}
-
-/*
- DESCRIPTION
- insert a 'node' in the list that starts from 'head' in the correct
- position (as found by lfind)
-
- RETURN
- 0 - inserted
- not 0 - a pointer to a duplicate (not pinned and thus unusable)
-
- NOTE
- it uses pins[0..2], on return all pins are removed.
- if there're nodes with the same key value, a new node is added before them.
-*/
-static LF_SLIST *linsert(LF_SLIST * volatile *head, CHARSET_INFO *cs,
- LF_SLIST *node, LF_PINS *pins, uint flags)
-{
- CURSOR cursor;
- int res;
-
- for (;;)
- {
- if (lfind(head, cs, node->hashnr, node->key, node->keylen,
- &cursor, pins) &&
- (flags & LF_HASH_UNIQUE))
- {
- res= 0; /* duplicate found */
- break;
- }
- else
- {
- node->link= (intptr)cursor.curr;
- DBUG_ASSERT(node->link != (intptr)node); /* no circular references */
- DBUG_ASSERT(cursor.prev != &node->link); /* no circular references */
- if (my_atomic_casptr((void **)cursor.prev, (void **)&cursor.curr, node))
- {
- res= 1; /* inserted ok */
- break;
- }
- }
- }
- _lf_unpin(pins, 0);
- _lf_unpin(pins, 1);
- _lf_unpin(pins, 2);
- /*
- Note that cursor.curr is not pinned here and the pointer is unreliable,
- the object may dissapear anytime. But if it points to a dummy node, the
- pointer is safe, because dummy nodes are never freed - initialize_bucket()
- uses this fact.
- */
- return res ? 0 : cursor.curr;
-}
-
-/*
- DESCRIPTION
- deletes a node as identified by hashnr/keey/keylen from the list
- that starts from 'head'
-
- RETURN
- 0 - ok
- 1 - not found
-
- NOTE
- it uses pins[0..2], on return all pins are removed.
-*/
-static int ldelete(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr,
- const uchar *key, uint keylen, LF_PINS *pins)
-{
- CURSOR cursor;
- int res;
-
- for (;;)
- {
- if (!lfind(head, cs, hashnr, key, keylen, &cursor, pins))
- {
- res= 1; /* not found */
- break;
- }
- else
- {
- /* mark the node deleted */
- if (my_atomic_casptr((void **)&(cursor.curr->link),
- (void **)&cursor.next,
- (void *)(((intptr)cursor.next) | 1)))
- {
- /* and remove it from the list */
- if (my_atomic_casptr((void **)cursor.prev,
- (void **)&cursor.curr, cursor.next))
- _lf_alloc_free(pins, cursor.curr);
- else
- {
- /*
- somebody already "helped" us and removed the node ?
- Let's check if we need to help that someone too!
- (to ensure the number of "set DELETED flag" actions
- is equal to the number of "remove from the list" actions)
- */
- lfind(head, cs, hashnr, key, keylen, &cursor, pins);
- }
- res= 0;
- break;
- }
- }
- }
- _lf_unpin(pins, 0);
- _lf_unpin(pins, 1);
- _lf_unpin(pins, 2);
- return res;
-}
-
-/*
- DESCRIPTION
- searches for a node as identified by hashnr/keey/keylen in the list
- that starts from 'head'
-
- RETURN
- 0 - not found
- node - found
-
- NOTE
- it uses pins[0..2], on return the pin[2] keeps the node found
- all other pins are removed.
-*/
-static LF_SLIST *lsearch(LF_SLIST * volatile *head, CHARSET_INFO *cs,
- uint32 hashnr, const uchar *key, uint keylen,
- LF_PINS *pins)
-{
- CURSOR cursor;
- int res= lfind(head, cs, hashnr, key, keylen, &cursor, pins);
- if (res)
- _lf_pin(pins, 2, cursor.curr);
- _lf_unpin(pins, 0);
- _lf_unpin(pins, 1);
- return res ? cursor.curr : 0;
-}
-
-static inline const uchar* hash_key(const LF_HASH *hash,
- const uchar *record, size_t *length)
-{
- if (hash->get_key)
- return (*hash->get_key)(record, length, 0);
- *length= hash->key_length;
- return record + hash->key_offset;
-}
-
-/*
- Compute the hash key value from the raw key.
-
- @note, that the hash value is limited to 2^31, because we need one
- bit to distinguish between normal and dummy nodes.
-*/
-static inline uint calc_hash(LF_HASH *hash, const uchar *key, uint keylen)
-{
- ulong nr1= 1, nr2= 4;
- hash->charset->coll->hash_sort(hash->charset, (uchar*) key, keylen,
- &nr1, &nr2);
- return nr1 & INT_MAX32;
-}
-
-#define MAX_LOAD 1.0 /* average number of elements in a bucket */
-
-static int initialize_bucket(LF_HASH *, LF_SLIST * volatile*, uint, LF_PINS *);
-
-/*
- Initializes lf_hash, the arguments are compatible with hash_init
-
- @note element_size sets both the size of allocated memory block for
- lf_alloc and a size of memcpy'ed block size in lf_hash_insert. Typically
- they are the same, indeed. But LF_HASH::element_size can be decreased
- after lf_hash_init, and then lf_alloc will allocate larger block that
- lf_hash_insert will copy over. It is desireable if part of the element
- is expensive to initialize - for example if there is a mutex or
- DYNAMIC_ARRAY. In this case they should be initialize in the
- LF_ALLOCATOR::constructor, and lf_hash_insert should not overwrite them.
- See wt_init() for example.
-*/
-void lf_hash_init(LF_HASH *hash, uint element_size, uint flags,
- uint key_offset, uint key_length, my_hash_get_key get_key,
- CHARSET_INFO *charset)
-{
- lf_alloc_init(&hash->alloc, sizeof(LF_SLIST)+element_size,
- offsetof(LF_SLIST, key));
- lf_dynarray_init(&hash->array, sizeof(LF_SLIST *));
- hash->size= 1;
- hash->count= 0;
- hash->element_size= element_size;
- hash->flags= flags;
- hash->charset= charset ? charset : &my_charset_bin;
- hash->key_offset= key_offset;
- hash->key_length= key_length;
- hash->get_key= get_key;
- DBUG_ASSERT(get_key ? !key_offset && !key_length : key_length);
-}
-
-void lf_hash_destroy(LF_HASH *hash)
-{
- LF_SLIST *el, **head= (LF_SLIST **)_lf_dynarray_value(&hash->array, 0);
-
- if (unlikely(!head))
- return;
- el= *head;
-
- while (el)
- {
- intptr next= el->link;
- if (el->hashnr & 1)
- lf_alloc_direct_free(&hash->alloc, el); /* normal node */
- else
- my_free(el); /* dummy node */
- el= (LF_SLIST *)next;
- }
- lf_alloc_destroy(&hash->alloc);
- lf_dynarray_destroy(&hash->array);
-}
-
-/*
- DESCRIPTION
- inserts a new element to a hash. it will have a _copy_ of
- data, not a pointer to it.
-
- RETURN
- 0 - inserted
- 1 - didn't (unique key conflict)
- -1 - out of memory
-
- NOTE
- see linsert() for pin usage notes
-*/
-int lf_hash_insert(LF_HASH *hash, LF_PINS *pins, const void *data)
-{
- int csize, bucket, hashnr;
- LF_SLIST *node, * volatile *el;
-
- lf_rwlock_by_pins(pins);
- node= (LF_SLIST *)_lf_alloc_new(pins);
- if (unlikely(!node))
- return -1;
- memcpy(node+1, data, hash->element_size);
- node->key= hash_key(hash, (uchar *)(node+1), &node->keylen);
- hashnr= calc_hash(hash, node->key, node->keylen);
- bucket= hashnr % hash->size;
- el= _lf_dynarray_lvalue(&hash->array, bucket);
- if (unlikely(!el))
- return -1;
- if (*el == NULL && unlikely(initialize_bucket(hash, el, bucket, pins)))
- return -1;
- node->hashnr= my_reverse_bits(hashnr) | 1; /* normal node */
- if (linsert(el, hash->charset, node, pins, hash->flags))
- {
- _lf_alloc_free(pins, node);
- lf_rwunlock_by_pins(pins);
- return 1;
- }
- csize= hash->size;
- if ((my_atomic_add32(&hash->count, 1)+1.0) / csize > MAX_LOAD)
- my_atomic_cas32(&hash->size, &csize, csize*2);
- lf_rwunlock_by_pins(pins);
- return 0;
-}
-
-/*
- DESCRIPTION
- deletes an element with the given key from the hash (if a hash is
- not unique and there're many elements with this key - the "first"
- matching element is deleted)
- RETURN
- 0 - deleted
- 1 - didn't (not found)
- -1 - out of memory
- NOTE
- see ldelete() for pin usage notes
-*/
-int lf_hash_delete(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen)
-{
- LF_SLIST * volatile *el;
- uint bucket, hashnr= calc_hash(hash, (uchar *)key, keylen);
-
- bucket= hashnr % hash->size;
- lf_rwlock_by_pins(pins);
- el= _lf_dynarray_lvalue(&hash->array, bucket);
- if (unlikely(!el))
- return -1;
- /*
- note that we still need to initialize_bucket here,
- we cannot return "node not found", because an old bucket of that
- node may've been split and the node was assigned to a new bucket
- that was never accessed before and thus is not initialized.
- */
- if (*el == NULL && unlikely(initialize_bucket(hash, el, bucket, pins)))
- return -1;
- if (ldelete(el, hash->charset, my_reverse_bits(hashnr) | 1,
- (uchar *)key, keylen, pins))
- {
- lf_rwunlock_by_pins(pins);
- return 1;
- }
- my_atomic_add32(&hash->count, -1);
- lf_rwunlock_by_pins(pins);
- return 0;
-}
-
-/*
- RETURN
- a pointer to an element with the given key (if a hash is not unique and
- there're many elements with this key - the "first" matching element)
- NULL if nothing is found
- MY_ERRPTR if OOM
-
- NOTE
- see lsearch() for pin usage notes
-*/
-void *lf_hash_search(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen)
-{
- LF_SLIST * volatile *el, *found;
- uint bucket, hashnr= calc_hash(hash, (uchar *)key, keylen);
-
- bucket= hashnr % hash->size;
- lf_rwlock_by_pins(pins);
- el= _lf_dynarray_lvalue(&hash->array, bucket);
- if (unlikely(!el))
- return MY_ERRPTR;
- if (*el == NULL && unlikely(initialize_bucket(hash, el, bucket, pins)))
- return MY_ERRPTR;
- found= lsearch(el, hash->charset, my_reverse_bits(hashnr) | 1,
- (uchar *)key, keylen, pins);
- lf_rwunlock_by_pins(pins);
- return found ? found+1 : 0;
-}
-
-static const uchar *dummy_key= (uchar*)"";
-
-/*
- RETURN
- 0 - ok
- -1 - out of memory
-*/
-static int initialize_bucket(LF_HASH *hash, LF_SLIST * volatile *node,
- uint bucket, LF_PINS *pins)
-{
- uint parent= my_clear_highest_bit(bucket);
- LF_SLIST *dummy= (LF_SLIST *)my_malloc(sizeof(LF_SLIST), MYF(MY_WME));
- LF_SLIST **tmp= 0, *cur;
- LF_SLIST * volatile *el= _lf_dynarray_lvalue(&hash->array, parent);
- if (unlikely(!el || !dummy))
- return -1;
- if (*el == NULL && bucket &&
- unlikely(initialize_bucket(hash, el, parent, pins)))
- return -1;
- dummy->hashnr= my_reverse_bits(bucket) | 0; /* dummy node */
- dummy->key= dummy_key;
- dummy->keylen= 0;
- if ((cur= linsert(el, hash->charset, dummy, pins, LF_HASH_UNIQUE)))
- {
- my_free(dummy);
- dummy= cur;
- }
- my_atomic_casptr((void **)node, (void **)&tmp, dummy);
- /*
- note that if the CAS above failed (after linsert() succeeded),
- it would mean that some other thread has executed linsert() for
- the same dummy node, its linsert() failed, it picked up our
- dummy node (in "dummy= cur") and executed the same CAS as above.
- Which means that even if CAS above failed we don't need to retry,
- and we should not free(dummy) - there's no memory leak here
- */
- return 0;
-}
diff --git a/dep/mysqllite/mysys/list.c b/dep/mysqllite/mysys/list.c
deleted file mode 100644
index e68fbf519d1..00000000000
--- a/dep/mysqllite/mysys/list.c
+++ /dev/null
@@ -1,114 +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 */
-
-/*
- Code for handling dubble-linked lists in C
-*/
-
-#include "mysys_priv.h"
-#include <my_list.h>
-
-
-
- /* Add a element to start of list */
-
-LIST *list_add(LIST *root, LIST *element)
-{
- DBUG_ENTER("list_add");
- DBUG_PRINT("enter",("root: 0x%lx element: 0x%lx", (long) root, (long) element));
- if (root)
- {
- if (root->prev) /* If add in mid of list */
- root->prev->next= element;
- element->prev=root->prev;
- root->prev=element;
- }
- else
- element->prev=0;
- element->next=root;
- DBUG_RETURN(element); /* New root */
-}
-
-
-LIST *list_delete(LIST *root, LIST *element)
-{
- if (element->prev)
- element->prev->next=element->next;
- else
- root=element->next;
- if (element->next)
- element->next->prev=element->prev;
- return root;
-}
-
-
-void list_free(LIST *root, uint free_data)
-{
- LIST *next;
- while (root)
- {
- next=root->next;
- if (free_data)
- my_free(root->data);
- my_free(root);
- root=next;
- }
-}
-
-
-LIST *list_cons(void *data, LIST *list)
-{
- LIST *new_charset=(LIST*) my_malloc(sizeof(LIST),MYF(MY_FAE));
- if (!new_charset)
- return 0;
- new_charset->data=data;
- return list_add(list,new_charset);
-}
-
-
-LIST *list_reverse(LIST *root)
-{
- LIST *last;
-
- last=root;
- while (root)
- {
- last=root;
- root=root->next;
- last->next=last->prev;
- last->prev=root;
- }
- return last;
-}
-
-uint list_length(LIST *list)
-{
- uint count;
- for (count=0 ; list ; list=list->next, count++) ;
- return count;
-}
-
-
-int list_walk(LIST *list, list_walk_action action, uchar* argument)
-{
- int error=0;
- while (list)
- {
- if ((error = (*action)(list->data,argument)))
- return error;
- list=list_rest(list);
- }
- return 0;
-}
diff --git a/dep/mysqllite/mysys/md5.c b/dep/mysqllite/mysys/md5.c
deleted file mode 100644
index 2388cebedc4..00000000000
--- a/dep/mysqllite/mysys/md5.c
+++ /dev/null
@@ -1,325 +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 */
-
-/*
- * This code implements the MD5 message-digest algorithm.
- * The algorithm is due to Ron Rivest. This code was
- * written by Colin Plumb in 1993, no copyright is claimed.
- * This code is in the public domain; do with it what you wish.
- *
- * Equivalent code is available from RSA Data Security, Inc.
- * This code has been tested against that, and is equivalent,
- * except that you don't need to include two pages of legalese
- * with every copy.
- *
- * To compute the message digest of a chunk of bytes, declare an
- * MD5Context structure, pass it to MD5Init, call MD5Update as
- * needed on buffers full of bytes, and then call MD5Final, which
- * will fill a supplied 16-byte array with the digest.
- */
-
-/* This code was modified in 1997 by Jim Kingdon of Cyclic Software to
- not require an integer type which is exactly 32 bits. This work
- draws on the changes for the same purpose by Tatu Ylonen
- <ylo@cs.hut.fi> as part of SSH, but since I didn't actually use
- that code, there is no copyright issue. I hereby disclaim
- copyright in any changes I have made; this code remains in the
- public domain. */
-
-#include <my_global.h>
-#include <m_string.h>
-#include "my_md5.h"
-
-#include <string.h> /* for memcpy() and memset() */
-
-
-static void
-my_MD5Transform (cvs_uint32 buf[4], const unsigned char in[64]);
-
-/* Little-endian byte-swapping routines. Note that these do not
- depend on the size of datatypes such as uint32, nor do they require
- us to detect the endianness of the machine we are running on. It
- is possible they should be macros for speed, but I would be
- surprised if they were a performance bottleneck for MD5. */
-
-static uint32 getu32 (const unsigned char *addr)
-{
- return (((((unsigned long)addr[3] << 8) | addr[2]) << 8)
- | addr[1]) << 8 | addr[0];
-}
-
-static void
-putu32 (uint32 data, unsigned char *addr)
-{
- addr[0] = (unsigned char)data;
- addr[1] = (unsigned char)(data >> 8);
- addr[2] = (unsigned char)(data >> 16);
- addr[3] = (unsigned char)(data >> 24);
-}
-
-/*
- Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
- initialization constants.
-*/
-void
-my_MD5Init (my_MD5Context *ctx)
-{
- ctx->buf[0] = 0x67452301;
- ctx->buf[1] = 0xefcdab89;
- ctx->buf[2] = 0x98badcfe;
- ctx->buf[3] = 0x10325476;
-
- ctx->bits[0] = 0;
- ctx->bits[1] = 0;
-}
-
-/*
- Update context to reflect the concatenation of another buffer full
- of bytes.
-*/
-void
-my_MD5Update (my_MD5Context *ctx, unsigned char const *buf, unsigned len)
-{
- uint32 t;
-
- /* Update bitcount */
-
- t = ctx->bits[0];
- if ((ctx->bits[0] = (t + ((uint32)len << 3)) & 0xffffffff) < t)
- ctx->bits[1]++; /* Carry from low to high */
- ctx->bits[1] += len >> 29;
-
- t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
-
- /* Handle any leading odd-sized chunks */
-
- if ( t ) {
- unsigned char *p = ctx->in + t;
-
- t = 64-t;
- if (len < t) {
- memcpy(p, buf, len);
- return;
- }
- memcpy(p, buf, t);
- my_MD5Transform (ctx->buf, ctx->in);
- buf += t;
- len -= t;
- }
-
- /* Process data in 64-byte chunks */
-
- while (len >= 64) {
- memcpy(ctx->in, buf, 64);
- my_MD5Transform (ctx->buf, ctx->in);
- buf += 64;
- len -= 64;
- }
-
- /* Handle any remaining bytes of data. */
-
- memcpy(ctx->in, buf, len);
-}
-
-/*
- Final wrapup - pad to 64-byte boundary with the bit pattern
- 1 0* (64-bit count of bits processed, MSB-first)
-*/
-void
-my_MD5Final (unsigned char digest[16], my_MD5Context *ctx)
-{
- unsigned count;
- unsigned char *p;
-
- /* Compute number of bytes mod 64 */
- count = (ctx->bits[0] >> 3) & 0x3F;
-
- /* Set the first char of padding to 0x80. This is safe since there is
- always at least one byte free */
- p = ctx->in + count;
- *p++ = 0x80;
-
- /* Bytes of padding needed to make 64 bytes */
- count = 64 - 1 - count;
-
- /* Pad out to 56 mod 64 */
- if (count < 8) {
- /* Two lots of padding: Pad the first block to 64 bytes */
- memset(p, 0, count);
- my_MD5Transform (ctx->buf, ctx->in);
-
- /* Now fill the next block with 56 bytes */
- memset(ctx->in, 0, 56);
- } else {
- /* Pad block to 56 bytes */
- memset(p, 0, count-8);
- }
-
- /* Append length in bits and transform */
- putu32(ctx->bits[0], ctx->in + 56);
- putu32(ctx->bits[1], ctx->in + 60);
-
- my_MD5Transform (ctx->buf, ctx->in);
- putu32(ctx->buf[0], digest);
- putu32(ctx->buf[1], digest + 4);
- putu32(ctx->buf[2], digest + 8);
- putu32(ctx->buf[3], digest + 12);
- memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
-}
-
-#ifndef ASM_MD5
-
-/* The four core functions - F1 is optimized somewhat */
-
-/* #define F1(x, y, z) (x & y | ~x & z) */
-#define F1(x, y, z) (z ^ (x & (y ^ z)))
-#define F2(x, y, z) F1(z, x, y)
-#define F3(x, y, z) (x ^ y ^ z)
-#define F4(x, y, z) (y ^ (x | ~z))
-
-/* This is the central step in the MD5 algorithm. */
-#define MD5STEP(f, w, x, y, z, data, s) \
- ( w += f(x, y, z) + data, w &= 0xffffffff, w = w<<s | w>>(32-s), w += x )
-
-/*
- * The core of the MD5 algorithm, this alters an existing MD5 hash to
- * reflect the addition of 16 longwords of new data. MD5Update blocks
- * the data and converts bytes into longwords for this routine.
- */
-static void
-my_MD5Transform (uint32 buf[4], const unsigned char inraw[64])
-{
- register uint32 a, b, c, d;
- uint32 in[16];
- int i;
-
- for (i = 0; i < 16; ++i)
- in[i] = getu32 (inraw + 4 * i);
-
- a = buf[0];
- b = buf[1];
- c = buf[2];
- d = buf[3];
-
- MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7);
- MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
- MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
- MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
- MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7);
- MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
- MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
- MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
- MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7);
- MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
- MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
- MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
- MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7);
- MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
- MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
- MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
-
- MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5);
- MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9);
- MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
- MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
- MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5);
- MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9);
- MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
- MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
- MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5);
- MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9);
- MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
- MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
- MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5);
- MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9);
- MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
- MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
-
- MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4);
- MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
- MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
- MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
- MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4);
- MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
- MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
- MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
- MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4);
- MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
- MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
- MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
- MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4);
- MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
- MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
- MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
-
- MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6);
- MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
- MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
- MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
- MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6);
- MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
- MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
- MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
- MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6);
- MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
- MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
- MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
- MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6);
- MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
- MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
- MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
-
- buf[0] += a;
- buf[1] += b;
- buf[2] += c;
- buf[3] += d;
-}
-#endif
-
-#ifdef TEST
-/*
- Simple test program. Can use it to manually run the tests from
- RFC1321 for example.
-*/
-#include <stdio.h>
-
-int
-main (int argc, char **argv)
-{
- my_MD5Context context;
- unsigned char checksum[16];
- int i;
- int j;
-
- if (argc < 2)
- {
- fprintf (stderr, "usage: %s string-to-hash\n", argv[0]);
- exit (1);
- }
- for (j = 1; j < argc; ++j)
- {
- printf ("MD5 (\"%s\") = ", argv[j]);
- my_MD5Init (&context);
- my_MD5Update (&context, argv[j], strlen (argv[j]));
- my_MD5Final (checksum, &context);
- for (i = 0; i < 16; i++)
- {
- printf ("%02x", (unsigned int) checksum[i]);
- }
- printf ("\n");
- }
- return 0;
-}
-#endif /* TEST */
diff --git a/dep/mysqllite/mysys/mf_arr_appstr.c b/dep/mysqllite/mysys/mf_arr_appstr.c
deleted file mode 100644
index 1edbea9df4a..00000000000
--- a/dep/mysqllite/mysys/mf_arr_appstr.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright (C) 2007 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 <m_string.h> /* strcmp() */
-
-
-/**
- Append str to array, or move to the end if it already exists
-
- @param str String to be appended
- @param array The array, terminated by a NULL element, all unused elements
- pre-initialized to NULL
- @param size Size of the array; array must be terminated by a NULL
- pointer, so can hold size - 1 elements
-
- @retval FALSE Success
- @retval TRUE Failure, array is full
-*/
-
-my_bool array_append_string_unique(const char *str,
- const char **array, size_t size)
-{
- const char **p;
- /* end points at the terminating NULL element */
- const char **end= array + size - 1;
- DBUG_ASSERT(*end == NULL);
-
- for (p= array; *p; ++p)
- {
- if (strcmp(*p, str) == 0)
- break;
- }
- if (p >= end)
- return TRUE; /* Array is full */
-
- DBUG_ASSERT(*p == NULL || strcmp(*p, str) == 0);
-
- while (*(p + 1))
- {
- *p= *(p + 1);
- ++p;
- }
-
- DBUG_ASSERT(p < end);
- *p= str;
-
- return FALSE; /* Success */
-}
diff --git a/dep/mysqllite/mysys/mf_cache.c b/dep/mysqllite/mysys/mf_cache.c
deleted file mode 100644
index 691532c0d80..00000000000
--- a/dep/mysqllite/mysys/mf_cache.c
+++ /dev/null
@@ -1,121 +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 */
-
-/* Open a temporary file and cache it with io_cache. Delete it on close */
-
-#include "mysys_priv.h"
-#include <m_string.h>
-#include "my_static.h"
-#include "mysys_err.h"
-
- /*
- Remove an open tempfile so that it doesn't survive
- if we crash; If the operating system doesn't support
- this, just remember the file name for later removal
- */
-
-static my_bool cache_remove_open_tmp(IO_CACHE *cache __attribute__((unused)),
- const char *name)
-{
-#if O_TEMPORARY == 0
-#if !defined(CANT_DELETE_OPEN_FILES)
- /* The following should always succeed */
- (void) my_delete(name,MYF(MY_WME | ME_NOINPUT));
-#else
- int length;
- if (!(cache->file_name=
- (char*) my_malloc((length=strlen(name)+1),MYF(MY_WME))))
- {
- my_close(cache->file,MYF(0));
- cache->file = -1;
- errno=my_errno=ENOMEM;
- return 1;
- }
- memcpy(cache->file_name,name,length);
-#endif
-#endif /* O_TEMPORARY == 0 */
- return 0;
-}
-
- /*
- ** Open tempfile cached by IO_CACHE
- ** Should be used when no seeks are done (only reinit_io_buff)
- ** Return 0 if cache is inited ok
- ** The actual file is created when the IO_CACHE buffer gets filled
- ** If dir is not given, use TMPDIR.
- */
-
-my_bool open_cached_file(IO_CACHE *cache, const char* dir, const char *prefix,
- size_t cache_size, myf cache_myflags)
-{
- DBUG_ENTER("open_cached_file");
- cache->dir= dir ? my_strdup(dir,MYF(cache_myflags & MY_WME)) : (char*) 0;
- cache->prefix= (prefix ? my_strdup(prefix,MYF(cache_myflags & MY_WME)) :
- (char*) 0);
- cache->file_name=0;
- cache->buffer=0; /* Mark that not open */
- if (!init_io_cache(cache,-1,cache_size,WRITE_CACHE,0L,0,
- MYF(cache_myflags | MY_NABP)))
- {
- DBUG_RETURN(0);
- }
- my_free(cache->dir);
- my_free(cache->prefix);
- DBUG_RETURN(1);
-}
-
- /* Create the temporary file */
-
-my_bool real_open_cached_file(IO_CACHE *cache)
-{
- char name_buff[FN_REFLEN];
- int error=1;
- DBUG_ENTER("real_open_cached_file");
- if ((cache->file=create_temp_file(name_buff, cache->dir, cache->prefix,
- (O_RDWR | O_BINARY | O_TRUNC |
- O_TEMPORARY | O_SHORT_LIVED),
- MYF(MY_WME))) >= 0)
- {
- error=0;
- cache_remove_open_tmp(cache, name_buff);
- }
- DBUG_RETURN(error);
-}
-
-
-void close_cached_file(IO_CACHE *cache)
-{
- DBUG_ENTER("close_cached_file");
- if (my_b_inited(cache))
- {
- File file=cache->file;
- cache->file= -1; /* Don't flush data */
- (void) end_io_cache(cache);
- if (file >= 0)
- {
- (void) my_close(file,MYF(0));
-#ifdef CANT_DELETE_OPEN_FILES
- if (cache->file_name)
- {
- (void) my_delete(cache->file_name,MYF(MY_WME | ME_NOINPUT));
- my_free(cache->file_name);
- }
-#endif
- }
- my_free(cache->dir);
- my_free(cache->prefix);
- }
- DBUG_VOID_RETURN;
-}
diff --git a/dep/mysqllite/mysys/mf_dirname.c b/dep/mysqllite/mysys/mf_dirname.c
deleted file mode 100644
index 5a9440483e4..00000000000
--- a/dep/mysqllite/mysys/mf_dirname.c
+++ /dev/null
@@ -1,154 +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 <m_string.h>
-
- /* Functions definied in this file */
-
-size_t dirname_length(const char *name)
-{
- register char *pos, *gpos;
-#ifdef BASKSLASH_MBTAIL
- CHARSET_INFO *fs= fs_character_set();
-#endif
-#ifdef FN_DEVCHAR
- if ((pos=(char*)strrchr(name,FN_DEVCHAR)) == 0)
-#endif
- pos=(char*) name-1;
-
- gpos= pos++;
- for ( ; *pos ; pos++) /* Find last FN_LIBCHAR */
- {
-#ifdef BASKSLASH_MBTAIL
- uint l;
- if (use_mb(fs) && (l= my_ismbchar(fs, pos, pos + 3)))
- {
- pos+= l - 1;
- continue;
- }
-#endif
- if (*pos == FN_LIBCHAR || *pos == '/')
- gpos=pos;
- }
- return (size_t) (gpos+1-(char*) name);
-}
-
-
-/*
- Gives directory part of filename. Directory ends with '/'
-
- SYNOPSIS
- dirname_part()
- to Store directory name here
- name Original name
- to_length Store length of 'to' here
-
- RETURN
- # Length of directory part in 'name'
-*/
-
-size_t dirname_part(char *to, const char *name, size_t *to_res_length)
-{
- size_t length;
- DBUG_ENTER("dirname_part");
- DBUG_PRINT("enter",("'%s'",name));
-
- length=dirname_length(name);
- *to_res_length= (size_t) (convert_dirname(to, name, name+length) - to);
- DBUG_RETURN(length);
-} /* dirname */
-
-
-/*
- Convert directory name to use under this system
-
- SYNPOSIS
- convert_dirname()
- 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. May be == to
- from_end Pointer at end of filename (normally end \0)
-
- IMPLEMENTATION
- If Windows converts '/' to '\'
- Adds a FN_LIBCHAR to end if the result string if there isn't one
- and the last isn't dev_char.
- Copies data from 'from' until ASCII(0) for until from == from_end
- If you want to use the whole 'from' string, just send NullS as the
- last argument.
-
- If the result string is larger than FN_REFLEN -1, then it's cut.
-
- RETURN
- Returns pointer to end \0 in to
-*/
-
-#ifndef FN_DEVCHAR
-#define FN_DEVCHAR '\0' /* For easier code */
-#endif
-
-char *convert_dirname(char *to, const char *from, const char *from_end)
-{
- char *to_org=to;
-#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)
- from_end=from+FN_REFLEN -2;
-
-#if FN_LIBCHAR != '/'
- {
- for (; from != from_end && *from ; from++)
- {
- if (*from == '/')
- *to++= FN_LIBCHAR;
- else
- {
-#ifdef BACKSLASH_MBTAIL
- uint l;
- if (use_mb(fs) && (l= my_ismbchar(fs, from, from + 3)))
- {
- memmove(to, from, l);
- to+= l;
- from+= l - 1;
- to_org= to; /* Don't look inside mbchar */
- }
- else
-#endif
- {
- *to++= *from;
- }
- }
- }
- *to=0;
- }
-#else
- /* This is ok even if to == from, becasue we need to cut the string */
- to= strmake(to, from, (size_t) (from_end-from));
-#endif
-
- /* Add FN_LIBCHAR to the end of directory path */
- if (to != to_org && (to[-1] != FN_LIBCHAR && to[-1] != FN_DEVCHAR))
- {
- *to++=FN_LIBCHAR;
- *to=0;
- }
- DBUG_RETURN(to); /* Pointer to end of dir */
-} /* convert_dirname */
diff --git a/dep/mysqllite/mysys/mf_fn_ext.c b/dep/mysqllite/mysys/mf_fn_ext.c
deleted file mode 100644
index c872f2993c4..00000000000
--- a/dep/mysqllite/mysys/mf_fn_ext.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 <m_string.h>
-
-/*
- Return a pointer to the extension of the filename.
-
- SYNOPSIS
- fn_ext()
- name Name of file
-
- DESCRIPTION
- The extension is defined as everything after the first extension character
- (normally '.') after the directory name.
-
- RETURN VALUES
- Pointer to to the extension character. If there isn't any extension,
- points at the end ASCII(0) of the filename.
-*/
-
-char *fn_ext(const char *name)
-{
- register const char *pos, *gpos;
- DBUG_ENTER("fn_ext");
- DBUG_PRINT("mfunkt",("name: '%s'",name));
-
-#if defined(FN_DEVCHAR) || defined(BASKSLASH_MBTAIL)
- {
- char buff[FN_REFLEN];
- size_t res_length;
- gpos= name+ dirname_part(buff,(char*) name, &res_length);
- }
-#else
- if (!(gpos= strrchr(name, FN_LIBCHAR)))
- gpos= name;
-#endif
- pos=strchr(gpos,FN_EXTCHAR);
- DBUG_RETURN((char*) (pos ? pos : strend(gpos)));
-} /* fn_ext */
diff --git a/dep/mysqllite/mysys/mf_format.c b/dep/mysqllite/mysys/mf_format.c
deleted file mode 100644
index 6afa2938fa3..00000000000
--- a/dep/mysqllite/mysys/mf_format.c
+++ /dev/null
@@ -1,142 +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 <m_string.h>
-
-/*
- Formats a filename with possible replace of directory of extension
- Function can handle the case where 'to' == 'name'
- For a description of the flag values, consult my_sys.h
- The arguments should be in unix format.
-*/
-
-char * fn_format(char * to, const char *name, const char *dir,
- const char *extension, uint flag)
-{
- char dev[FN_REFLEN], buff[FN_REFLEN], *pos, *startpos;
- const char *ext;
- reg1 size_t length;
- size_t dev_length;
- DBUG_ENTER("fn_format");
- DBUG_PRINT("enter",("name: %s dir: %s extension: %s flag: %d",
- name,dir,extension,flag));
-
- /* Copy and skip directory */
- name+=(length=dirname_part(dev, (startpos=(char *) name), &dev_length));
- if (length == 0 || (flag & MY_REPLACE_DIR))
- {
- /* Use given directory */
- convert_dirname(dev,dir,NullS); /* Fix to this OS */
- }
- else if ((flag & MY_RELATIVE_PATH) && !test_if_hard_path(dev))
- {
- /* Put 'dir' before the given path */
- strmake(buff,dev,sizeof(buff)-1);
- pos=convert_dirname(dev,dir,NullS);
- strmake(pos,buff,sizeof(buff)-1- (int) (pos-dev));
- }
-
- if (flag & MY_PACK_FILENAME)
- pack_dirname(dev,dev); /* Put in ./.. and ~/.. */
- if (flag & MY_UNPACK_FILENAME)
- (void) unpack_dirname(dev,dev); /* Replace ~/.. with dir */
-
- if (!(flag & MY_APPEND_EXT) &&
- (pos= (char*) strchr(name,FN_EXTCHAR)) != NullS)
- {
- if ((flag & MY_REPLACE_EXT) == 0) /* If we should keep old ext */
- {
- length=strlength(name); /* Use old extension */
- ext = "";
- }
- else
- {
- length= (size_t) (pos-(char*) name); /* Change extension */
- ext= extension;
- }
- }
- else
- {
- length=strlength(name); /* No ext, use the now one */
- ext=extension;
- }
-
- if (strlen(dev)+length+strlen(ext) >= FN_REFLEN || length >= FN_LEN )
- {
- /* To long path, return original or NULL */
- size_t tmp_length;
- if (flag & MY_SAFE_PATH)
- DBUG_RETURN(NullS);
- tmp_length= strlength(startpos);
- DBUG_PRINT("error",("dev: '%s' ext: '%s' length: %u",dev,ext,
- (uint) length));
- (void) strmake(to,startpos,min(tmp_length,FN_REFLEN-1));
- }
- else
- {
- if (to == startpos)
- {
- bmove(buff,(uchar*) name,length); /* Save name for last copy */
- name=buff;
- }
- pos=strmake(strmov(to,dev),name,length);
- (void) strmov(pos,ext); /* Don't convert extension */
- }
- /*
- If MY_RETURN_REAL_PATH and MY_RESOLVE_SYMLINK is given, only do
- realpath if the file is a symbolic link
- */
- if (flag & MY_RETURN_REAL_PATH)
- (void) my_realpath(to, to, MYF(flag & MY_RESOLVE_SYMLINKS ?
- MY_RESOLVE_LINK: 0));
- else if (flag & MY_RESOLVE_SYMLINKS)
- {
- strmov(buff,to);
- (void) my_readlink(to, buff, MYF(0));
- }
- DBUG_RETURN(to);
-} /* fn_format */
-
-
-/*
- strlength(const string str)
- Return length of string with end-space:s not counted.
-*/
-
-size_t strlength(const char *str)
-{
- reg1 const char * pos;
- reg2 const char * found;
- DBUG_ENTER("strlength");
-
- pos= found= str;
-
- while (*pos)
- {
- if (*pos != ' ')
- {
- while (*++pos && *pos != ' ') {};
- if (!*pos)
- {
- found=pos; /* String ends here */
- break;
- }
- }
- found=pos;
- while (*++pos == ' ') {};
- }
- DBUG_RETURN((size_t) (found - str));
-} /* strlength */
diff --git a/dep/mysqllite/mysys/mf_getdate.c b/dep/mysqllite/mysys/mf_getdate.c
deleted file mode 100644
index 9475bebd107..00000000000
--- a/dep/mysqllite/mysys/mf_getdate.c
+++ /dev/null
@@ -1,81 +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 */
-
-/* Get date in a printable form: yyyy-mm-dd hh:mm:ss */
-
-#include "mysys_priv.h"
-#include <m_string.h>
-
-/*
- get date as string
-
- SYNOPSIS
- get_date()
- to - string where date will be written
- flag - format of date:
- If flag & GETDATE_TIME Return date and time
- If flag & GETDATE_SHORT_DATE Return short date format YYMMDD
- If flag & GETDATE_HHMMSSTIME Return time in HHMMDD format.
- If flag & GETDATE_GMT Date/time in GMT
- If flag & GETDATE_FIXEDLENGTH Return fixed length date/time
- date - for conversion
-*/
-
-
-void get_date(register char * to, int flag, time_t date)
-{
- reg2 struct tm *start_time;
- time_t skr;
-#if defined(HAVE_LOCALTIME_R) && defined(_REENTRANT)
- struct tm tm_tmp;
-#endif
-
- skr=date ? (time_t) date : my_time(0);
-#if defined(HAVE_LOCALTIME_R) && defined(_REENTRANT)
- if (flag & GETDATE_GMT)
- gmtime_r(&skr,&tm_tmp);
- else
- localtime_r(&skr,&tm_tmp);
- start_time= &tm_tmp;
-#else
- if (flag & GETDATE_GMT)
- start_time= gmtime(&skr);
- else
- start_time= localtime(&skr);
-#endif
- if (flag & GETDATE_SHORT_DATE)
- sprintf(to,"%02d%02d%02d",
- start_time->tm_year % 100,
- start_time->tm_mon+1,
- start_time->tm_mday);
- else
- sprintf(to, ((flag & GETDATE_FIXEDLENGTH) ?
- "%4d-%02d-%02d" : "%d-%02d-%02d"),
- start_time->tm_year+1900,
- start_time->tm_mon+1,
- start_time->tm_mday);
- if (flag & GETDATE_DATE_TIME)
- sprintf(strend(to),
- ((flag & GETDATE_FIXEDLENGTH) ?
- " %02d:%02d:%02d" : " %2d:%02d:%02d"),
- start_time->tm_hour,
- start_time->tm_min,
- start_time->tm_sec);
- else if (flag & GETDATE_HHMMSSTIME)
- sprintf(strend(to),"%02d%02d%02d",
- start_time->tm_hour,
- start_time->tm_min,
- start_time->tm_sec);
-} /* get_date */
diff --git a/dep/mysqllite/mysys/mf_iocache.c b/dep/mysqllite/mysys/mf_iocache.c
deleted file mode 100644
index 62e51ffb629..00000000000
--- a/dep/mysqllite/mysys/mf_iocache.c
+++ /dev/null
@@ -1,1949 +0,0 @@
-/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 */
-
-/*
- Cashing of files with only does (sequential) read or writes of fixed-
- length records. A read isn't allowed to go over file-length. A read is ok
- if it ends at file-length and next read can try to read after file-length
- (and get a EOF-error).
- Possibly use of asyncronic io.
- macros for read and writes for faster io.
- Used instead of FILE when reading or writing whole files.
- This code makes mf_rec_cache obsolete (currently only used by ISAM)
- One can change info->pos_in_file to a higher value to skip bytes in file if
- also info->read_pos is set to info->read_end.
- If called through open_cached_file(), then the temporary file will
- only be created if a write exeeds the file buffer or if one calls
- my_b_flush_io_cache().
-
- If one uses SEQ_READ_APPEND, then two buffers are allocated, one for
- reading and another for writing. Reads are first done from disk and
- then done from the write buffer. This is an efficient way to read
- from a log file when one is writing to it at the same time.
- For this to work, the file has to be opened in append mode!
- Note that when one uses SEQ_READ_APPEND, one MUST write using
- my_b_append ! This is needed because we need to lock the mutex
- every time we access the write buffer.
-
-TODO:
- When one SEQ_READ_APPEND and we are reading and writing at the same time,
- each time the write buffer gets full and it's written to disk, we will
- always do a disk read to read a part of the buffer from disk to the
- read buffer.
- This should be fixed so that when we do a my_b_flush_io_cache() and
- we have been reading the write buffer, we should transfer the rest of the
- write buffer to the read buffer before we start to reuse it.
-*/
-
-#include "mysys_priv.h"
-#include <m_string.h>
-#ifdef HAVE_AIOWAIT
-#include "mysys_err.h"
-static void my_aiowait(my_aio_result *result);
-#endif
-#include <errno.h>
-
-#define lock_append_buffer(info) \
- mysql_mutex_lock(&(info)->append_buffer_lock)
-#define unlock_append_buffer(info) \
- mysql_mutex_unlock(&(info)->append_buffer_lock)
-
-#define IO_ROUND_UP(X) (((X)+IO_SIZE-1) & ~(IO_SIZE-1))
-#define IO_ROUND_DN(X) ( (X) & ~(IO_SIZE-1))
-
-/*
- Setup internal pointers inside IO_CACHE
-
- SYNOPSIS
- setup_io_cache()
- info IO_CACHE handler
-
- NOTES
- This is called on automaticly on init or reinit of IO_CACHE
- It must be called externally if one moves or copies an IO_CACHE
- object.
-*/
-
-void setup_io_cache(IO_CACHE* info)
-{
- /* Ensure that my_b_tell() and my_b_bytes_in_cache works */
- if (info->type == WRITE_CACHE)
- {
- info->current_pos= &info->write_pos;
- info->current_end= &info->write_end;
- }
- else
- {
- info->current_pos= &info->read_pos;
- info->current_end= &info->read_end;
- }
-}
-
-
-static void
-init_functions(IO_CACHE* info)
-{
- enum cache_type type= info->type;
- switch (type) {
- case READ_NET:
- /*
- Must be initialized by the caller. The problem is that
- _my_b_net_read has to be defined in sql directory because of
- the dependency on THD, and therefore cannot be visible to
- programs that link against mysys but know nothing about THD, such
- as myisamchk
- */
- break;
- case SEQ_READ_APPEND:
- info->read_function = _my_b_seq_read;
- info->write_function = 0; /* Force a core if used */
- break;
- default:
- info->read_function = info->share ? _my_b_read_r : _my_b_read;
- info->write_function = _my_b_write;
- }
-
- setup_io_cache(info);
-}
-
-
-/*
- Initialize an IO_CACHE object
-
- SYNOPSOS
- init_io_cache()
- info cache handler to initialize
- file File that should be associated to to the handler
- If == -1 then real_open_cached_file()
- will be called when it's time to open file.
- cachesize Size of buffer to allocate for read/write
- If == 0 then use my_default_record_cache_size
- type Type of cache
- seek_offset Where cache should start reading/writing
- use_async_io Set to 1 of we should use async_io (if avaiable)
- cache_myflags Bitmap of differnt flags
- MY_WME | MY_FAE | MY_NABP | MY_FNABP |
- MY_DONT_CHECK_FILESIZE
-
- RETURN
- 0 ok
- # error
-*/
-
-int init_io_cache(IO_CACHE *info, File file, size_t cachesize,
- enum cache_type type, my_off_t seek_offset,
- pbool use_async_io, myf cache_myflags)
-{
- size_t min_cache;
- my_off_t pos;
- my_off_t end_of_file= ~(my_off_t) 0;
- DBUG_ENTER("init_io_cache");
- DBUG_PRINT("enter",("cache: 0x%lx type: %d pos: %ld",
- (ulong) info, (int) type, (ulong) seek_offset));
-
- info->file= file;
- info->type= TYPE_NOT_SET; /* Don't set it until mutex are created */
- info->pos_in_file= seek_offset;
- info->pre_close = info->pre_read = info->post_read = 0;
- info->arg = 0;
- info->alloced_buffer = 0;
- info->buffer=0;
- info->seek_not_done= 0;
-
- if (file >= 0)
- {
- pos= mysql_file_tell(file, MYF(0));
- if ((pos == (my_off_t) -1) && (my_errno == ESPIPE))
- {
- /*
- This kind of object doesn't support seek() or tell(). Don't set a
- flag that will make us again try to seek() later and fail.
- */
- info->seek_not_done= 0;
- /*
- Additionally, if we're supposed to start somewhere other than the
- the beginning of whatever this file is, then somebody made a bad
- assumption.
- */
- DBUG_ASSERT(seek_offset == 0);
- }
- else
- info->seek_not_done= test(seek_offset != pos);
- }
-
- info->disk_writes= 0;
- info->share=0;
-
- if (!cachesize && !(cachesize= my_default_record_cache_size))
- DBUG_RETURN(1); /* No cache requested */
- min_cache=use_async_io ? IO_SIZE*4 : IO_SIZE*2;
- if (type == READ_CACHE || type == SEQ_READ_APPEND)
- { /* Assume file isn't growing */
- if (!(cache_myflags & MY_DONT_CHECK_FILESIZE))
- {
- /* Calculate end of file to avoid allocating oversized buffers */
- end_of_file= mysql_file_seek(file, 0L, MY_SEEK_END, MYF(0));
- /* Need to reset seek_not_done now that we just did a seek. */
- info->seek_not_done= end_of_file == seek_offset ? 0 : 1;
- if (end_of_file < seek_offset)
- end_of_file=seek_offset;
- /* Trim cache size if the file is very small */
- if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1)
- {
- cachesize= (size_t) (end_of_file-seek_offset)+IO_SIZE*2-1;
- use_async_io=0; /* No need to use async */
- }
- }
- }
- cache_myflags &= ~MY_DONT_CHECK_FILESIZE;
- if (type != READ_NET && type != WRITE_NET)
- {
- /* Retry allocating memory in smaller blocks until we get one */
- cachesize= ((cachesize + min_cache-1) & ~(min_cache-1));
- for (;;)
- {
- size_t buffer_block;
- /*
- Unset MY_WAIT_IF_FULL bit if it is set, to prevent conflict with
- MY_ZEROFILL.
- */
- myf flags= (myf) (cache_myflags & ~(MY_WME | MY_WAIT_IF_FULL));
-
- if (cachesize < min_cache)
- cachesize = min_cache;
- buffer_block= cachesize;
- if (type == SEQ_READ_APPEND)
- buffer_block *= 2;
- if (cachesize == min_cache)
- flags|= (myf) MY_WME;
-
- if ((info->buffer= (uchar*) my_malloc(buffer_block, flags)) != 0)
- {
- info->write_buffer=info->buffer;
- if (type == SEQ_READ_APPEND)
- info->write_buffer = info->buffer + cachesize;
- info->alloced_buffer=1;
- break; /* Enough memory found */
- }
- if (cachesize == min_cache)
- DBUG_RETURN(2); /* Can't alloc cache */
- /* Try with less memory */
- cachesize= (cachesize*3/4 & ~(min_cache-1));
- }
- }
-
- DBUG_PRINT("info",("init_io_cache: cachesize = %lu", (ulong) cachesize));
- info->read_length=info->buffer_length=cachesize;
- info->myflags=cache_myflags & ~(MY_NABP | MY_FNABP);
- info->request_pos= info->read_pos= info->write_pos = info->buffer;
- if (type == SEQ_READ_APPEND)
- {
- info->append_read_pos = info->write_pos = info->write_buffer;
- info->write_end = info->write_buffer + info->buffer_length;
- mysql_mutex_init(key_IO_CACHE_append_buffer_lock,
- &info->append_buffer_lock, MY_MUTEX_INIT_FAST);
- }
-#if defined(SAFE_MUTEX)
- else
- {
- /* Clear mutex so that safe_mutex will notice that it's not initialized */
- bzero((char*) &info->append_buffer_lock, sizeof(info));
- }
-#endif
-
- if (type == WRITE_CACHE)
- info->write_end=
- info->buffer+info->buffer_length- (seek_offset & (IO_SIZE-1));
- else
- info->read_end=info->buffer; /* Nothing in cache */
-
- /* End_of_file may be changed by user later */
- info->end_of_file= end_of_file;
- info->error=0;
- info->type= type;
- init_functions(info);
-#ifdef HAVE_AIOWAIT
- if (use_async_io && ! my_disable_async_io)
- {
- DBUG_PRINT("info",("Using async io"));
- info->read_length/=2;
- info->read_function=_my_b_async_read;
- }
- info->inited=info->aio_result.pending=0;
-#endif
- DBUG_RETURN(0);
-} /* init_io_cache */
-
- /* Wait until current request is ready */
-
-#ifdef HAVE_AIOWAIT
-static void my_aiowait(my_aio_result *result)
-{
- if (result->pending)
- {
- struct aio_result_t *tmp;
- for (;;)
- {
- if ((int) (tmp=aiowait((struct timeval *) 0)) == -1)
- {
- if (errno == EINTR)
- continue;
- DBUG_PRINT("error",("No aio request, error: %d",errno));
- result->pending=0; /* Assume everythings is ok */
- break;
- }
- ((my_aio_result*) tmp)->pending=0;
- if ((my_aio_result*) tmp == result)
- break;
- }
- }
- return;
-}
-#endif
-
-
-/*
- Use this to reset cache to re-start reading or to change the type
- between READ_CACHE <-> WRITE_CACHE
- If we are doing a reinit of a cache where we have the start of the file
- in the cache, we are reusing this memory without flushing it to disk.
-*/
-
-my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
- my_off_t seek_offset,
- pbool use_async_io __attribute__((unused)),
- pbool clear_cache)
-{
- DBUG_ENTER("reinit_io_cache");
- DBUG_PRINT("enter",("cache: 0x%lx type: %d seek_offset: %lu clear_cache: %d",
- (ulong) info, type, (ulong) seek_offset,
- (int) clear_cache));
-
- /* One can't do reinit with the following types */
- DBUG_ASSERT(type != READ_NET && info->type != READ_NET &&
- type != WRITE_NET && info->type != WRITE_NET &&
- type != SEQ_READ_APPEND && info->type != SEQ_READ_APPEND);
-
- /* If the whole file is in memory, avoid flushing to disk */
- if (! clear_cache &&
- seek_offset >= info->pos_in_file &&
- seek_offset <= my_b_tell(info))
- {
- /* Reuse current buffer without flushing it to disk */
- uchar *pos;
- if (info->type == WRITE_CACHE && type == READ_CACHE)
- {
- info->read_end=info->write_pos;
- info->end_of_file=my_b_tell(info);
- /*
- Trigger a new seek only if we have a valid
- file handle.
- */
- info->seek_not_done= (info->file != -1);
- }
- else if (type == WRITE_CACHE)
- {
- if (info->type == READ_CACHE)
- {
- info->write_end=info->write_buffer+info->buffer_length;
- info->seek_not_done=1;
- }
- info->end_of_file = ~(my_off_t) 0;
- }
- pos=info->request_pos+(seek_offset-info->pos_in_file);
- if (type == WRITE_CACHE)
- info->write_pos=pos;
- else
- info->read_pos= pos;
-#ifdef HAVE_AIOWAIT
- my_aiowait(&info->aio_result); /* Wait for outstanding req */
-#endif
- }
- else
- {
- /*
- If we change from WRITE_CACHE to READ_CACHE, assume that everything
- after the current positions should be ignored
- */
- if (info->type == WRITE_CACHE && type == READ_CACHE)
- info->end_of_file=my_b_tell(info);
- /* flush cache if we want to reuse it */
- if (!clear_cache && my_b_flush_io_cache(info,1))
- DBUG_RETURN(1);
- info->pos_in_file=seek_offset;
- /* Better to do always do a seek */
- info->seek_not_done=1;
- info->request_pos=info->read_pos=info->write_pos=info->buffer;
- if (type == READ_CACHE)
- {
- info->read_end=info->buffer; /* Nothing in cache */
- }
- else
- {
- info->write_end=(info->buffer + info->buffer_length -
- (seek_offset & (IO_SIZE-1)));
- info->end_of_file= ~(my_off_t) 0;
- }
- }
- info->type=type;
- info->error=0;
- init_functions(info);
-
-#ifdef HAVE_AIOWAIT
- if (use_async_io && ! my_disable_async_io &&
- ((ulong) info->buffer_length <
- (ulong) (info->end_of_file - seek_offset)))
- {
- info->read_length=info->buffer_length/2;
- info->read_function=_my_b_async_read;
- }
- info->inited=0;
-#endif
- DBUG_RETURN(0);
-} /* reinit_io_cache */
-
-
-
-/*
- Read buffered.
-
- SYNOPSIS
- _my_b_read()
- info IO_CACHE pointer
- Buffer Buffer to retrieve count bytes from file
- Count Number of bytes to read into Buffer
-
- NOTE
- This function is only called from the my_b_read() macro when there
- isn't enough characters in the buffer to satisfy the request.
-
- WARNING
-
- When changing this function, be careful with handling file offsets
- (end-of_file, pos_in_file). Do not cast them to possibly smaller
- types than my_off_t unless you can be sure that their value fits.
- Same applies to differences of file offsets.
-
- When changing this function, check _my_b_read_r(). It might need the
- same change.
-
- RETURN
- 0 we succeeded in reading all data
- 1 Error: couldn't read requested characters. In this case:
- If info->error == -1, we got a read error.
- Otherwise info->error contains the number of bytes in Buffer.
-*/
-
-int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
-{
- size_t length,diff_length,left_length, max_length;
- my_off_t pos_in_file;
- DBUG_ENTER("_my_b_read");
-
- /* If the buffer is not empty yet, copy what is available. */
- if ((left_length= (size_t) (info->read_end-info->read_pos)))
- {
- DBUG_ASSERT(Count >= left_length); /* User is not using my_b_read() */
- memcpy(Buffer,info->read_pos, left_length);
- Buffer+=left_length;
- Count-=left_length;
- }
-
- /* pos_in_file always point on where info->buffer was read */
- pos_in_file=info->pos_in_file+ (size_t) (info->read_end - info->buffer);
-
- /*
- Whenever a function which operates on IO_CACHE flushes/writes
- some part of the IO_CACHE to disk it will set the property
- "seek_not_done" to indicate this to other functions operating
- on the IO_CACHE.
- */
- if (info->seek_not_done)
- {
- if ((mysql_file_seek(info->file, pos_in_file, MY_SEEK_SET, MYF(0))
- != MY_FILEPOS_ERROR))
- {
- /* No error, reset seek_not_done flag. */
- info->seek_not_done= 0;
- }
- else
- {
- /*
- If the seek failed and the error number is ESPIPE, it is because
- info->file is a pipe or socket or FIFO. We never should have tried
- to seek on that. See Bugs#25807 and #22828 for more info.
- */
- DBUG_ASSERT(my_errno != ESPIPE);
- info->error= -1;
- DBUG_RETURN(1);
- }
- }
-
- /*
- Calculate, how much we are within a IO_SIZE block. Ideally this
- should be zero.
- */
- diff_length= (size_t) (pos_in_file & (IO_SIZE-1));
-
- /*
- If more than a block plus the rest of the current block is wanted,
- we do read directly, without filling the buffer.
- */
- if (Count >= (size_t) (IO_SIZE+(IO_SIZE-diff_length)))
- { /* Fill first intern buffer */
- size_t read_length;
- if (info->end_of_file <= pos_in_file)
- {
- /* End of file. Return, what we did copy from the buffer. */
- info->error= (int) left_length;
- DBUG_RETURN(1);
- }
- /*
- Crop the wanted count to a multiple of IO_SIZE and subtract,
- what we did already read from a block. That way, the read will
- end aligned with a block.
- */
- length=(Count & (size_t) ~(IO_SIZE-1))-diff_length;
- if ((read_length= mysql_file_read(info->file,Buffer, length, info->myflags))
- != length)
- {
- /*
- If we didn't get, what we wanted, we either return -1 for a read
- error, or (it's end of file), how much we got in total.
- */
- info->error= (read_length == (size_t) -1 ? -1 :
- (int) (read_length+left_length));
- DBUG_RETURN(1);
- }
- Count-=length;
- Buffer+=length;
- pos_in_file+=length;
- left_length+=length;
- diff_length=0;
- }
-
- /*
- At this point, we want less than one and a partial block.
- We will read a full cache, minus the number of bytes, we are
- within a block already. So we will reach new alignment.
- */
- max_length= info->read_length-diff_length;
- /* We will not read past end of file. */
- if (info->type != READ_FIFO &&
- max_length > (info->end_of_file - pos_in_file))
- max_length= (size_t) (info->end_of_file - pos_in_file);
- /*
- If there is nothing left to read,
- we either are done, or we failed to fulfill the request.
- Otherwise, we read max_length into the cache.
- */
- if (!max_length)
- {
- if (Count)
- {
- /* We couldn't fulfil the request. Return, how much we got. */
- info->error= left_length;
- DBUG_RETURN(1);
- }
- length=0; /* Didn't read any chars */
- }
- else if ((length= mysql_file_read(info->file,info->buffer, max_length,
- info->myflags)) < Count ||
- length == (size_t) -1)
- {
- /*
- We got an read error, or less than requested (end of file).
- If not a read error, copy, what we got.
- */
- if (length != (size_t) -1)
- memcpy(Buffer, info->buffer, length);
- info->pos_in_file= pos_in_file;
- /* For a read error, return -1, otherwise, what we got in total. */
- info->error= length == (size_t) -1 ? -1 : (int) (length+left_length);
- info->read_pos=info->read_end=info->buffer;
- DBUG_RETURN(1);
- }
- /*
- Count is the remaining number of bytes requested.
- length is the amount of data in the cache.
- Read Count bytes from the cache.
- */
- info->read_pos=info->buffer+Count;
- info->read_end=info->buffer+length;
- info->pos_in_file=pos_in_file;
- memcpy(Buffer, info->buffer, Count);
- DBUG_RETURN(0);
-}
-
-
-/*
- Prepare IO_CACHE for shared use.
-
- SYNOPSIS
- init_io_cache_share()
- read_cache A read cache. This will be copied for
- every thread after setup.
- cshare The share.
- write_cache If non-NULL a write cache that is to be
- synchronized with the read caches.
- num_threads Number of threads sharing the cache
- including the write thread if any.
-
- DESCRIPTION
-
- The shared cache is used so: One IO_CACHE is initialized with
- init_io_cache(). This includes the allocation of a buffer. Then a
- share is allocated and init_io_cache_share() is called with the io
- cache and the share. Then the io cache is copied for each thread. So
- every thread has its own copy of IO_CACHE. But the allocated buffer
- is shared because cache->buffer is the same for all caches.
-
- One thread reads data from the file into the buffer. All threads
- read from the buffer, but every thread maintains its own set of
- pointers into the buffer. When all threads have used up the buffer
- contents, one of the threads reads the next block of data into the
- buffer. To accomplish this, each thread enters the cache lock before
- accessing the buffer. They wait in lock_io_cache() until all threads
- joined the lock. The last thread entering the lock is in charge of
- reading from file to buffer. It wakes all threads when done.
-
- Synchronizing a write cache to the read caches works so: Whenever
- the write buffer needs a flush, the write thread enters the lock and
- waits for all other threads to enter the lock too. They do this when
- they have used up the read buffer. When all threads are in the lock,
- the write thread copies the write buffer to the read buffer and
- wakes all threads.
-
- share->running_threads is the number of threads not being in the
- cache lock. When entering lock_io_cache() the number is decreased.
- When the thread that fills the buffer enters unlock_io_cache() the
- number is reset to the number of threads. The condition
- running_threads == 0 means that all threads are in the lock. Bumping
- up the number to the full count is non-intuitive. But increasing the
- number by one for each thread that leaves the lock could lead to a
- solo run of one thread. The last thread to join a lock reads from
- file to buffer, wakes the other threads, processes the data in the
- cache and enters the lock again. If no other thread left the lock
- meanwhile, it would think it's the last one again and read the next
- block...
-
- The share has copies of 'error', 'buffer', 'read_end', and
- 'pos_in_file' from the thread that filled the buffer. We may not be
- able to access this information directly from its cache because the
- thread may be removed from the share before the variables could be
- copied by all other threads. Or, if a write buffer is synchronized,
- it would change its 'pos_in_file' after waking the other threads,
- possibly before they could copy its value.
-
- However, the 'buffer' variable in the share is for a synchronized
- write cache. It needs to know where to put the data. Otherwise it
- would need access to the read cache of one of the threads that is
- not yet removed from the share.
-
- RETURN
- void
-*/
-
-void init_io_cache_share(IO_CACHE *read_cache, IO_CACHE_SHARE *cshare,
- IO_CACHE *write_cache, uint num_threads)
-{
- DBUG_ENTER("init_io_cache_share");
- DBUG_PRINT("io_cache_share", ("read_cache: 0x%lx share: 0x%lx "
- "write_cache: 0x%lx threads: %u",
- (long) read_cache, (long) cshare,
- (long) write_cache, num_threads));
-
- DBUG_ASSERT(num_threads > 1);
- DBUG_ASSERT(read_cache->type == READ_CACHE);
- DBUG_ASSERT(!write_cache || (write_cache->type == WRITE_CACHE));
-
- mysql_mutex_init(key_IO_CACHE_SHARE_mutex,
- &cshare->mutex, MY_MUTEX_INIT_FAST);
- mysql_cond_init(key_IO_CACHE_SHARE_cond, &cshare->cond, 0);
- mysql_cond_init(key_IO_CACHE_SHARE_cond_writer, &cshare->cond_writer, 0);
-
- cshare->running_threads= num_threads;
- cshare->total_threads= num_threads;
- cshare->error= 0; /* Initialize. */
- cshare->buffer= read_cache->buffer;
- cshare->read_end= NULL; /* See function comment of lock_io_cache(). */
- cshare->pos_in_file= 0; /* See function comment of lock_io_cache(). */
- cshare->source_cache= write_cache; /* Can be NULL. */
-
- read_cache->share= cshare;
- read_cache->read_function= _my_b_read_r;
- read_cache->current_pos= NULL;
- read_cache->current_end= NULL;
-
- if (write_cache)
- write_cache->share= cshare;
-
- DBUG_VOID_RETURN;
-}
-
-
-/*
- Remove a thread from shared access to IO_CACHE.
-
- SYNOPSIS
- remove_io_thread()
- cache The IO_CACHE to be removed from the share.
-
- NOTE
-
- Every thread must do that on exit for not to deadlock other threads.
-
- The last thread destroys the pthread resources.
-
- A writer flushes its cache first.
-
- RETURN
- void
-*/
-
-void remove_io_thread(IO_CACHE *cache)
-{
- IO_CACHE_SHARE *cshare= cache->share;
- uint total;
- DBUG_ENTER("remove_io_thread");
-
- /* If the writer goes, it needs to flush the write cache. */
- if (cache == cshare->source_cache)
- flush_io_cache(cache);
-
- mysql_mutex_lock(&cshare->mutex);
- DBUG_PRINT("io_cache_share", ("%s: 0x%lx",
- (cache == cshare->source_cache) ?
- "writer" : "reader", (long) cache));
-
- /* Remove from share. */
- total= --cshare->total_threads;
- DBUG_PRINT("io_cache_share", ("remaining threads: %u", total));
-
- /* Detach from share. */
- cache->share= NULL;
-
- /* If the writer goes, let the readers know. */
- if (cache == cshare->source_cache)
- {
- DBUG_PRINT("io_cache_share", ("writer leaves"));
- cshare->source_cache= NULL;
- }
-
- /* If all threads are waiting for me to join the lock, wake them. */
- if (!--cshare->running_threads)
- {
- DBUG_PRINT("io_cache_share", ("the last running thread leaves, wake all"));
- mysql_cond_signal(&cshare->cond_writer);
- mysql_cond_broadcast(&cshare->cond);
- }
-
- mysql_mutex_unlock(&cshare->mutex);
-
- if (!total)
- {
- DBUG_PRINT("io_cache_share", ("last thread removed, destroy share"));
- mysql_cond_destroy (&cshare->cond_writer);
- mysql_cond_destroy (&cshare->cond);
- mysql_mutex_destroy(&cshare->mutex);
- }
-
- DBUG_VOID_RETURN;
-}
-
-
-/*
- Lock IO cache and wait for all other threads to join.
-
- SYNOPSIS
- lock_io_cache()
- cache The cache of the thread entering the lock.
- pos File position of the block to read.
- Unused for the write thread.
-
- DESCRIPTION
-
- Wait for all threads to finish with the current buffer. We want
- all threads to proceed in concert. The last thread to join
- lock_io_cache() will read the block from file and all threads start
- to use it. Then they will join again for reading the next block.
-
- The waiting threads detect a fresh buffer by comparing
- cshare->pos_in_file with the position they want to process next.
- Since the first block may start at position 0, we take
- cshare->read_end as an additional condition. This variable is
- initialized to NULL and will be set after a block of data is written
- to the buffer.
-
- RETURN
- 1 OK, lock in place, go ahead and read.
- 0 OK, unlocked, another thread did the read.
-*/
-
-static int lock_io_cache(IO_CACHE *cache, my_off_t pos)
-{
- IO_CACHE_SHARE *cshare= cache->share;
- DBUG_ENTER("lock_io_cache");
-
- /* Enter the lock. */
- mysql_mutex_lock(&cshare->mutex);
- cshare->running_threads--;
- DBUG_PRINT("io_cache_share", ("%s: 0x%lx pos: %lu running: %u",
- (cache == cshare->source_cache) ?
- "writer" : "reader", (long) cache, (ulong) pos,
- cshare->running_threads));
-
- if (cshare->source_cache)
- {
- /* A write cache is synchronized to the read caches. */
-
- if (cache == cshare->source_cache)
- {
- /* The writer waits until all readers are here. */
- while (cshare->running_threads)
- {
- DBUG_PRINT("io_cache_share", ("writer waits in lock"));
- mysql_cond_wait(&cshare->cond_writer, &cshare->mutex);
- }
- DBUG_PRINT("io_cache_share", ("writer awoke, going to copy"));
-
- /* Stay locked. Leave the lock later by unlock_io_cache(). */
- DBUG_RETURN(1);
- }
-
- /* The last thread wakes the writer. */
- if (!cshare->running_threads)
- {
- DBUG_PRINT("io_cache_share", ("waking writer"));
- mysql_cond_signal(&cshare->cond_writer);
- }
-
- /*
- Readers wait until the data is copied from the writer. Another
- reason to stop waiting is the removal of the write thread. If this
- happens, we leave the lock with old data in the buffer.
- */
- while ((!cshare->read_end || (cshare->pos_in_file < pos)) &&
- cshare->source_cache)
- {
- DBUG_PRINT("io_cache_share", ("reader waits in lock"));
- mysql_cond_wait(&cshare->cond, &cshare->mutex);
- }
-
- /*
- If the writer was removed from the share while this thread was
- asleep, we need to simulate an EOF condition. The writer cannot
- reset the share variables as they might still be in use by readers
- of the last block. When we awake here then because the last
- joining thread signalled us. If the writer is not the last, it
- will not signal. So it is safe to clear the buffer here.
- */
- if (!cshare->read_end || (cshare->pos_in_file < pos))
- {
- DBUG_PRINT("io_cache_share", ("reader found writer removed. EOF"));
- cshare->read_end= cshare->buffer; /* Empty buffer. */
- cshare->error= 0; /* EOF is not an error. */
- }
- }
- else
- {
- /*
- There are read caches only. The last thread arriving in
- lock_io_cache() continues with a locked cache and reads the block.
- */
- if (!cshare->running_threads)
- {
- DBUG_PRINT("io_cache_share", ("last thread joined, going to read"));
- /* Stay locked. Leave the lock later by unlock_io_cache(). */
- DBUG_RETURN(1);
- }
-
- /*
- All other threads wait until the requested block is read by the
- last thread arriving. Another reason to stop waiting is the
- removal of a thread. If this leads to all threads being in the
- lock, we have to continue also. The first of the awaken threads
- will then do the read.
- */
- while ((!cshare->read_end || (cshare->pos_in_file < pos)) &&
- cshare->running_threads)
- {
- DBUG_PRINT("io_cache_share", ("reader waits in lock"));
- mysql_cond_wait(&cshare->cond, &cshare->mutex);
- }
-
- /* If the block is not yet read, continue with a locked cache and read. */
- if (!cshare->read_end || (cshare->pos_in_file < pos))
- {
- DBUG_PRINT("io_cache_share", ("reader awoke, going to read"));
- /* Stay locked. Leave the lock later by unlock_io_cache(). */
- DBUG_RETURN(1);
- }
-
- /* Another thread did read the block already. */
- }
- DBUG_PRINT("io_cache_share", ("reader awoke, going to process %u bytes",
- (uint) (cshare->read_end ? (size_t)
- (cshare->read_end - cshare->buffer) :
- 0)));
-
- /*
- Leave the lock. Do not call unlock_io_cache() later. The thread that
- filled the buffer did this and marked all threads as running.
- */
- mysql_mutex_unlock(&cshare->mutex);
- DBUG_RETURN(0);
-}
-
-
-/*
- Unlock IO cache.
-
- SYNOPSIS
- unlock_io_cache()
- cache The cache of the thread leaving the lock.
-
- NOTE
- This is called by the thread that filled the buffer. It marks all
- threads as running and awakes them. This must not be done by any
- other thread.
-
- Do not signal cond_writer. Either there is no writer or the writer
- is the only one who can call this function.
-
- The reason for resetting running_threads to total_threads before
- waking all other threads is that it could be possible that this
- thread is so fast with processing the buffer that it enters the lock
- before even one other thread has left it. If every awoken thread
- would increase running_threads by one, this thread could think that
- he is again the last to join and would not wait for the other
- threads to process the data.
-
- RETURN
- void
-*/
-
-static void unlock_io_cache(IO_CACHE *cache)
-{
- IO_CACHE_SHARE *cshare= cache->share;
- DBUG_ENTER("unlock_io_cache");
- DBUG_PRINT("io_cache_share", ("%s: 0x%lx pos: %lu running: %u",
- (cache == cshare->source_cache) ?
- "writer" : "reader",
- (long) cache, (ulong) cshare->pos_in_file,
- cshare->total_threads));
-
- cshare->running_threads= cshare->total_threads;
- mysql_cond_broadcast(&cshare->cond);
- mysql_mutex_unlock(&cshare->mutex);
- DBUG_VOID_RETURN;
-}
-
-
-/*
- Read from IO_CACHE when it is shared between several threads.
-
- SYNOPSIS
- _my_b_read_r()
- cache IO_CACHE pointer
- Buffer Buffer to retrieve count bytes from file
- Count Number of bytes to read into Buffer
-
- NOTE
- This function is only called from the my_b_read() macro when there
- isn't enough characters in the buffer to satisfy the request.
-
- IMPLEMENTATION
-
- It works as follows: when a thread tries to read from a file (that
- is, after using all the data from the (shared) buffer), it just
- hangs on lock_io_cache(), waiting for other threads. When the very
- last thread attempts a read, lock_io_cache() returns 1, the thread
- does actual IO and unlock_io_cache(), which signals all the waiting
- threads that data is in the buffer.
-
- WARNING
-
- When changing this function, be careful with handling file offsets
- (end-of_file, pos_in_file). Do not cast them to possibly smaller
- types than my_off_t unless you can be sure that their value fits.
- Same applies to differences of file offsets. (Bug #11527)
-
- When changing this function, check _my_b_read(). It might need the
- same change.
-
- RETURN
- 0 we succeeded in reading all data
- 1 Error: can't read requested characters
-*/
-
-int _my_b_read_r(register IO_CACHE *cache, uchar *Buffer, size_t Count)
-{
- my_off_t pos_in_file;
- size_t length, diff_length, left_length;
- IO_CACHE_SHARE *cshare= cache->share;
- DBUG_ENTER("_my_b_read_r");
-
- if ((left_length= (size_t) (cache->read_end - cache->read_pos)))
- {
- DBUG_ASSERT(Count >= left_length); /* User is not using my_b_read() */
- memcpy(Buffer, cache->read_pos, left_length);
- Buffer+= left_length;
- Count-= left_length;
- }
- while (Count)
- {
- size_t cnt, len;
-
- pos_in_file= cache->pos_in_file + (cache->read_end - cache->buffer);
- diff_length= (size_t) (pos_in_file & (IO_SIZE-1));
- length=IO_ROUND_UP(Count+diff_length)-diff_length;
- length= ((length <= cache->read_length) ?
- length + IO_ROUND_DN(cache->read_length - length) :
- length - IO_ROUND_UP(length - cache->read_length));
- if (cache->type != READ_FIFO &&
- (length > (cache->end_of_file - pos_in_file)))
- length= (size_t) (cache->end_of_file - pos_in_file);
- if (length == 0)
- {
- cache->error= (int) left_length;
- DBUG_RETURN(1);
- }
- if (lock_io_cache(cache, pos_in_file))
- {
- /* With a synchronized write/read cache we won't come here... */
- DBUG_ASSERT(!cshare->source_cache);
- /*
- ... unless the writer has gone before this thread entered the
- lock. Simulate EOF in this case. It can be distinguished by
- cache->file.
- */
- if (cache->file < 0)
- len= 0;
- else
- {
- /*
- Whenever a function which operates on IO_CACHE flushes/writes
- some part of the IO_CACHE to disk it will set the property
- "seek_not_done" to indicate this to other functions operating
- on the IO_CACHE.
- */
- if (cache->seek_not_done)
- {
- if (mysql_file_seek(cache->file, pos_in_file, MY_SEEK_SET, MYF(0))
- == MY_FILEPOS_ERROR)
- {
- cache->error= -1;
- unlock_io_cache(cache);
- DBUG_RETURN(1);
- }
- }
- len= mysql_file_read(cache->file, cache->buffer, length, cache->myflags);
- }
- DBUG_PRINT("io_cache_share", ("read %lu bytes", (ulong) len));
-
- cache->read_end= cache->buffer + (len == (size_t) -1 ? 0 : len);
- cache->error= (len == length ? 0 : (int) len);
- cache->pos_in_file= pos_in_file;
-
- /* Copy important values to the share. */
- cshare->error= cache->error;
- cshare->read_end= cache->read_end;
- cshare->pos_in_file= pos_in_file;
-
- /* Mark all threads as running and wake them. */
- unlock_io_cache(cache);
- }
- else
- {
- /*
- With a synchronized write/read cache readers always come here.
- Copy important values from the share.
- */
- cache->error= cshare->error;
- cache->read_end= cshare->read_end;
- cache->pos_in_file= cshare->pos_in_file;
-
- len= ((cache->error == -1) ? (size_t) -1 :
- (size_t) (cache->read_end - cache->buffer));
- }
- cache->read_pos= cache->buffer;
- cache->seek_not_done= 0;
- if (len == 0 || len == (size_t) -1)
- {
- DBUG_PRINT("io_cache_share", ("reader error. len %lu left %lu",
- (ulong) len, (ulong) left_length));
- cache->error= (int) left_length;
- DBUG_RETURN(1);
- }
- cnt= (len > Count) ? Count : len;
- memcpy(Buffer, cache->read_pos, cnt);
- Count -= cnt;
- Buffer+= cnt;
- left_length+= cnt;
- cache->read_pos+= cnt;
- }
- DBUG_RETURN(0);
-}
-
-
-/*
- Copy data from write cache to read cache.
-
- SYNOPSIS
- copy_to_read_buffer()
- write_cache The write cache.
- write_buffer The source of data, mostly the cache buffer.
- write_length The number of bytes to copy.
-
- NOTE
- The write thread will wait for all read threads to join the cache
- lock. Then it copies the data over and wakes the read threads.
-
- RETURN
- void
-*/
-
-static void copy_to_read_buffer(IO_CACHE *write_cache,
- const uchar *write_buffer, size_t write_length)
-{
- IO_CACHE_SHARE *cshare= write_cache->share;
-
- DBUG_ASSERT(cshare->source_cache == write_cache);
- /*
- write_length is usually less or equal to buffer_length.
- It can be bigger if _my_b_write() is called with a big length.
- */
- while (write_length)
- {
- size_t copy_length= min(write_length, write_cache->buffer_length);
- int __attribute__((unused)) rc;
-
- rc= lock_io_cache(write_cache, write_cache->pos_in_file);
- /* The writing thread does always have the lock when it awakes. */
- DBUG_ASSERT(rc);
-
- memcpy(cshare->buffer, write_buffer, copy_length);
-
- cshare->error= 0;
- cshare->read_end= cshare->buffer + copy_length;
- cshare->pos_in_file= write_cache->pos_in_file;
-
- /* Mark all threads as running and wake them. */
- unlock_io_cache(write_cache);
-
- write_buffer+= copy_length;
- write_length-= copy_length;
- }
-}
-
-
-/*
- Do sequential read from the SEQ_READ_APPEND cache.
-
- We do this in three stages:
- - first read from info->buffer
- - then if there are still data to read, try the file descriptor
- - afterwards, if there are still data to read, try append buffer
-
- RETURNS
- 0 Success
- 1 Failed to read
-*/
-
-int _my_b_seq_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
-{
- size_t length, diff_length, left_length, save_count, max_length;
- my_off_t pos_in_file;
- save_count=Count;
-
- /* first, read the regular buffer */
- if ((left_length=(size_t) (info->read_end-info->read_pos)))
- {
- DBUG_ASSERT(Count > left_length); /* User is not using my_b_read() */
- memcpy(Buffer,info->read_pos, left_length);
- Buffer+=left_length;
- Count-=left_length;
- }
- lock_append_buffer(info);
-
- /* pos_in_file always point on where info->buffer was read */
- if ((pos_in_file=info->pos_in_file +
- (size_t) (info->read_end - info->buffer)) >= info->end_of_file)
- goto read_append_buffer;
-
- /*
- With read-append cache we must always do a seek before we read,
- because the write could have moved the file pointer astray
- */
- if (mysql_file_seek(info->file, pos_in_file, MY_SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR)
- {
- info->error= -1;
- unlock_append_buffer(info);
- return (1);
- }
- info->seek_not_done=0;
-
- diff_length= (size_t) (pos_in_file & (IO_SIZE-1));
-
- /* now the second stage begins - read from file descriptor */
- if (Count >= (size_t) (IO_SIZE+(IO_SIZE-diff_length)))
- {
- /* Fill first intern buffer */
- size_t read_length;
-
- length=(Count & (size_t) ~(IO_SIZE-1))-diff_length;
- if ((read_length= mysql_file_read(info->file,Buffer, length,
- info->myflags)) == (size_t) -1)
- {
- info->error= -1;
- unlock_append_buffer(info);
- return 1;
- }
- Count-=read_length;
- Buffer+=read_length;
- pos_in_file+=read_length;
-
- if (read_length != length)
- {
- /*
- We only got part of data; Read the rest of the data from the
- write buffer
- */
- goto read_append_buffer;
- }
- left_length+=length;
- diff_length=0;
- }
-
- max_length= info->read_length-diff_length;
- if (max_length > (info->end_of_file - pos_in_file))
- max_length= (size_t) (info->end_of_file - pos_in_file);
- if (!max_length)
- {
- if (Count)
- goto read_append_buffer;
- length=0; /* Didn't read any more chars */
- }
- else
- {
- length= mysql_file_read(info->file,info->buffer, max_length, info->myflags);
- if (length == (size_t) -1)
- {
- info->error= -1;
- unlock_append_buffer(info);
- return 1;
- }
- if (length < Count)
- {
- memcpy(Buffer, info->buffer, length);
- Count -= length;
- Buffer += length;
-
- /*
- added the line below to make
- DBUG_ASSERT(pos_in_file==info->end_of_file) pass.
- otherwise this does not appear to be needed
- */
- pos_in_file += length;
- goto read_append_buffer;
- }
- }
- unlock_append_buffer(info);
- info->read_pos=info->buffer+Count;
- info->read_end=info->buffer+length;
- info->pos_in_file=pos_in_file;
- memcpy(Buffer,info->buffer,(size_t) Count);
- return 0;
-
-read_append_buffer:
-
- /*
- Read data from the current write buffer.
- Count should never be == 0 here (The code will work even if count is 0)
- */
-
- {
- /* First copy the data to Count */
- size_t len_in_buff = (size_t) (info->write_pos - info->append_read_pos);
- size_t copy_len;
- size_t transfer_len;
-
- DBUG_ASSERT(info->append_read_pos <= info->write_pos);
- /*
- TODO: figure out if the assert below is needed or correct.
- */
- DBUG_ASSERT(pos_in_file == info->end_of_file);
- copy_len=min(Count, len_in_buff);
- memcpy(Buffer, info->append_read_pos, copy_len);
- info->append_read_pos += copy_len;
- Count -= copy_len;
- if (Count)
- info->error = save_count - Count;
-
- /* Fill read buffer with data from write buffer */
- memcpy(info->buffer, info->append_read_pos,
- (size_t) (transfer_len=len_in_buff - copy_len));
- info->read_pos= info->buffer;
- info->read_end= info->buffer+transfer_len;
- info->append_read_pos=info->write_pos;
- info->pos_in_file=pos_in_file+copy_len;
- info->end_of_file+=len_in_buff;
- }
- unlock_append_buffer(info);
- return Count ? 1 : 0;
-}
-
-
-#ifdef HAVE_AIOWAIT
-
-/*
- Read from the IO_CACHE into a buffer and feed asynchronously
- from disk when needed.
-
- SYNOPSIS
- _my_b_async_read()
- info IO_CACHE pointer
- Buffer Buffer to retrieve count bytes from file
- Count Number of bytes to read into Buffer
-
- RETURN VALUE
- -1 An error has occurred; my_errno is set.
- 0 Success
- 1 An error has occurred; IO_CACHE to error state.
-*/
-
-int _my_b_async_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
-{
- size_t length,read_length,diff_length,left_length,use_length,org_Count;
- size_t max_length;
- my_off_t next_pos_in_file;
- uchar *read_buffer;
-
- memcpy(Buffer,info->read_pos,
- (left_length= (size_t) (info->read_end-info->read_pos)));
- Buffer+=left_length;
- org_Count=Count;
- Count-=left_length;
-
- if (info->inited)
- { /* wait for read block */
- info->inited=0; /* No more block to read */
- my_aiowait(&info->aio_result); /* Wait for outstanding req */
- if (info->aio_result.result.aio_errno)
- {
- if (info->myflags & MY_WME)
- my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
- my_filename(info->file),
- info->aio_result.result.aio_errno);
- my_errno=info->aio_result.result.aio_errno;
- info->error= -1;
- return(1);
- }
- if (! (read_length= (size_t) info->aio_result.result.aio_return) ||
- read_length == (size_t) -1)
- {
- my_errno=0; /* For testing */
- info->error= (read_length == (size_t) -1 ? -1 :
- (int) (read_length+left_length));
- return(1);
- }
- info->pos_in_file+= (size_t) (info->read_end - info->request_pos);
-
- if (info->request_pos != info->buffer)
- info->request_pos=info->buffer;
- else
- info->request_pos=info->buffer+info->read_length;
- info->read_pos=info->request_pos;
- next_pos_in_file=info->aio_read_pos+read_length;
-
- /* Check if pos_in_file is changed
- (_ni_read_cache may have skipped some bytes) */
-
- if (info->aio_read_pos < info->pos_in_file)
- { /* Fix if skipped bytes */
- if (info->aio_read_pos + read_length < info->pos_in_file)
- {
- read_length=0; /* Skip block */
- next_pos_in_file=info->pos_in_file;
- }
- else
- {
- my_off_t offset= (info->pos_in_file - info->aio_read_pos);
- info->pos_in_file=info->aio_read_pos; /* Whe are here */
- info->read_pos=info->request_pos+offset;
- read_length-=offset; /* Bytes left from read_pos */
- }
- }
-#ifndef DBUG_OFF
- if (info->aio_read_pos > info->pos_in_file)
- {
- my_errno=EINVAL;
- return(info->read_length= (size_t) -1);
- }
-#endif
- /* Copy found bytes to buffer */
- length=min(Count,read_length);
- memcpy(Buffer,info->read_pos,(size_t) length);
- Buffer+=length;
- Count-=length;
- left_length+=length;
- info->read_end=info->rc_pos+read_length;
- info->read_pos+=length;
- }
- else
- next_pos_in_file=(info->pos_in_file+ (size_t)
- (info->read_end - info->request_pos));
-
- /* If reading large blocks, or first read or read with skip */
- if (Count)
- {
- if (next_pos_in_file == info->end_of_file)
- {
- info->error=(int) (read_length+left_length);
- return 1;
- }
-
- if (mysql_file_seek(info->file, next_pos_in_file, MY_SEEK_SET, MYF(0))
- == MY_FILEPOS_ERROR)
- {
- info->error= -1;
- return (1);
- }
-
- read_length=IO_SIZE*2- (size_t) (next_pos_in_file & (IO_SIZE-1));
- if (Count < read_length)
- { /* Small block, read to cache */
- if ((read_length=mysql_file_read(info->file,info->request_pos,
- read_length, info->myflags)) == (size_t) -1)
- return info->error= -1;
- use_length=min(Count,read_length);
- memcpy(Buffer,info->request_pos,(size_t) use_length);
- info->read_pos=info->request_pos+Count;
- info->read_end=info->request_pos+read_length;
- info->pos_in_file=next_pos_in_file; /* Start of block in cache */
- next_pos_in_file+=read_length;
-
- if (Count != use_length)
- { /* Didn't find hole block */
- if (info->myflags & (MY_WME | MY_FAE | MY_FNABP) && Count != org_Count)
- my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
- my_filename(info->file),my_errno);
- info->error=(int) (read_length+left_length);
- return 1;
- }
- }
- else
- { /* Big block, don't cache it */
- if ((read_length= mysql_file_read(info->file, Buffer, Count,info->myflags))
- != Count)
- {
- info->error= read_length == (size_t) -1 ? -1 : read_length+left_length;
- return 1;
- }
- info->read_pos=info->read_end=info->request_pos;
- info->pos_in_file=(next_pos_in_file+=Count);
- }
- }
-
- /* Read next block with asyncronic io */
- diff_length=(next_pos_in_file & (IO_SIZE-1));
- max_length= info->read_length - diff_length;
- if (max_length > info->end_of_file - next_pos_in_file)
- max_length= (size_t) (info->end_of_file - next_pos_in_file);
-
- if (info->request_pos != info->buffer)
- read_buffer=info->buffer;
- else
- read_buffer=info->buffer+info->read_length;
- info->aio_read_pos=next_pos_in_file;
- if (max_length)
- {
- info->aio_result.result.aio_errno=AIO_INPROGRESS; /* Marker for test */
- DBUG_PRINT("aioread",("filepos: %ld length: %lu",
- (ulong) next_pos_in_file, (ulong) max_length));
- if (aioread(info->file,read_buffer, max_length,
- (my_off_t) next_pos_in_file,MY_SEEK_SET,
- &info->aio_result.result))
- { /* Skip async io */
- my_errno=errno;
- DBUG_PRINT("error",("got error: %d, aio_result: %d from aioread, async skipped",
- errno, info->aio_result.result.aio_errno));
- if (info->request_pos != info->buffer)
- {
- bmove(info->buffer,info->request_pos,
- (size_t) (info->read_end - info->read_pos));
- info->request_pos=info->buffer;
- info->read_pos-=info->read_length;
- info->read_end-=info->read_length;
- }
- info->read_length=info->buffer_length; /* Use hole buffer */
- info->read_function=_my_b_read; /* Use normal IO_READ next */
- }
- else
- info->inited=info->aio_result.pending=1;
- }
- return 0; /* Block read, async in use */
-} /* _my_b_async_read */
-#endif
-
-
-/* Read one byte when buffer is empty */
-
-int _my_b_get(IO_CACHE *info)
-{
- uchar buff;
- IO_CACHE_CALLBACK pre_read,post_read;
- if ((pre_read = info->pre_read))
- (*pre_read)(info);
- if ((*(info)->read_function)(info,&buff,1))
- return my_b_EOF;
- if ((post_read = info->post_read))
- (*post_read)(info);
- return (int) (uchar) buff;
-}
-
-/*
- Write a byte buffer to IO_CACHE and flush to disk
- if IO_CACHE is full.
-
- RETURN VALUE
- 1 On error on write
- 0 On success
- -1 On error; my_errno contains error code.
-*/
-
-int _my_b_write(register IO_CACHE *info, const uchar *Buffer, size_t Count)
-{
- size_t rest_length,length;
-
- if (info->pos_in_file+info->buffer_length > info->end_of_file)
- {
- my_errno=errno=EFBIG;
- return info->error = -1;
- }
-
- rest_length= (size_t) (info->write_end - info->write_pos);
- memcpy(info->write_pos,Buffer,(size_t) rest_length);
- Buffer+=rest_length;
- Count-=rest_length;
- info->write_pos+=rest_length;
-
- if (my_b_flush_io_cache(info,1))
- return 1;
- if (Count >= IO_SIZE)
- { /* Fill first intern buffer */
- length=Count & (size_t) ~(IO_SIZE-1);
- if (info->seek_not_done)
- {
- /*
- Whenever a function which operates on IO_CACHE flushes/writes
- some part of the IO_CACHE to disk it will set the property
- "seek_not_done" to indicate this to other functions operating
- on the IO_CACHE.
- */
- if (mysql_file_seek(info->file, info->pos_in_file, MY_SEEK_SET, MYF(0)))
- {
- info->error= -1;
- return (1);
- }
- info->seek_not_done=0;
- }
- if (mysql_file_write(info->file, Buffer, length, info->myflags | MY_NABP))
- return info->error= -1;
-
- /*
- In case of a shared I/O cache with a writer we normally do direct
- write cache to read cache copy. Simulate this here by direct
- caller buffer to read cache copy. Do it after the write so that
- the cache readers actions on the flushed part can go in parallel
- with the write of the extra stuff. copy_to_read_buffer()
- synchronizes writer and readers so that after this call the
- readers can act on the extra stuff while the writer can go ahead
- and prepare the next output. copy_to_read_buffer() relies on
- info->pos_in_file.
- */
- if (info->share)
- copy_to_read_buffer(info, Buffer, length);
-
- Count-=length;
- Buffer+=length;
- info->pos_in_file+=length;
- }
- memcpy(info->write_pos,Buffer,(size_t) Count);
- info->write_pos+=Count;
- return 0;
-}
-
-
-/*
- Append a block to the write buffer.
- This is done with the buffer locked to ensure that we don't read from
- the write buffer before we are ready with it.
-*/
-
-int my_b_append(register IO_CACHE *info, const uchar *Buffer, size_t Count)
-{
- size_t rest_length,length;
-
- /*
- Assert that we cannot come here with a shared cache. If we do one
- day, we might need to add a call to copy_to_read_buffer().
- */
- DBUG_ASSERT(!info->share);
-
- lock_append_buffer(info);
- rest_length= (size_t) (info->write_end - info->write_pos);
- if (Count <= rest_length)
- goto end;
- memcpy(info->write_pos, Buffer, rest_length);
- Buffer+=rest_length;
- Count-=rest_length;
- info->write_pos+=rest_length;
- if (my_b_flush_io_cache(info,0))
- {
- unlock_append_buffer(info);
- return 1;
- }
- if (Count >= IO_SIZE)
- { /* Fill first intern buffer */
- length=Count & (size_t) ~(IO_SIZE-1);
- if (mysql_file_write(info->file,Buffer, length, info->myflags | MY_NABP))
- {
- unlock_append_buffer(info);
- return info->error= -1;
- }
- Count-=length;
- Buffer+=length;
- info->end_of_file+=length;
- }
-
-end:
- memcpy(info->write_pos,Buffer,(size_t) Count);
- info->write_pos+=Count;
- unlock_append_buffer(info);
- return 0;
-}
-
-
-int my_b_safe_write(IO_CACHE *info, const uchar *Buffer, size_t Count)
-{
- /*
- Sasha: We are not writing this with the ? operator to avoid hitting
- a possible compiler bug. At least gcc 2.95 cannot deal with
- several layers of ternary operators that evaluated comma(,) operator
- expressions inside - I do have a test case if somebody wants it
- */
- if (info->type == SEQ_READ_APPEND)
- return my_b_append(info, Buffer, Count);
- return my_b_write(info, Buffer, Count);
-}
-
-
-/*
- Write a block to disk where part of the data may be inside the record
- buffer. As all write calls to the data goes through the cache,
- we will never get a seek over the end of the buffer
-*/
-
-int my_block_write(register IO_CACHE *info, const uchar *Buffer, size_t Count,
- my_off_t pos)
-{
- size_t length;
- int error=0;
-
- /*
- Assert that we cannot come here with a shared cache. If we do one
- day, we might need to add a call to copy_to_read_buffer().
- */
- DBUG_ASSERT(!info->share);
-
- if (pos < info->pos_in_file)
- {
- /* Of no overlap, write everything without buffering */
- if (pos + Count <= info->pos_in_file)
- return mysql_file_pwrite(info->file, Buffer, Count, pos,
- info->myflags | MY_NABP);
- /* Write the part of the block that is before buffer */
- length= (uint) (info->pos_in_file - pos);
- if (mysql_file_pwrite(info->file, Buffer, length, pos, info->myflags | MY_NABP))
- info->error= error= -1;
- Buffer+=length;
- pos+= length;
- Count-= length;
-#ifndef HAVE_PREAD
- info->seek_not_done=1;
-#endif
- }
-
- /* Check if we want to write inside the used part of the buffer.*/
- length= (size_t) (info->write_end - info->buffer);
- if (pos < info->pos_in_file + length)
- {
- size_t offset= (size_t) (pos - info->pos_in_file);
- length-=offset;
- if (length > Count)
- length=Count;
- memcpy(info->buffer+offset, Buffer, length);
- Buffer+=length;
- Count-= length;
- /* Fix length of buffer if the new data was larger */
- if (info->buffer+length > info->write_pos)
- info->write_pos=info->buffer+length;
- if (!Count)
- return (error);
- }
- /* Write at the end of the current buffer; This is the normal case */
- if (_my_b_write(info, Buffer, Count))
- error= -1;
- return error;
-}
-
-
- /* Flush write cache */
-
-#define LOCK_APPEND_BUFFER if (need_append_buffer_lock) \
- lock_append_buffer(info);
-#define UNLOCK_APPEND_BUFFER if (need_append_buffer_lock) \
- unlock_append_buffer(info);
-
-int my_b_flush_io_cache(IO_CACHE *info,
- int need_append_buffer_lock __attribute__((unused)))
-{
- size_t length;
- my_off_t pos_in_file;
- my_bool append_cache= (info->type == SEQ_READ_APPEND);
- DBUG_ENTER("my_b_flush_io_cache");
- DBUG_PRINT("enter", ("cache: 0x%lx", (long) info));
-
- if (!append_cache)
- need_append_buffer_lock= 0;
-
- if (info->type == WRITE_CACHE || append_cache)
- {
- if (info->file == -1)
- {
- if (real_open_cached_file(info))
- DBUG_RETURN((info->error= -1));
- }
- LOCK_APPEND_BUFFER;
-
- if ((length=(size_t) (info->write_pos - info->write_buffer)))
- {
- /*
- In case of a shared I/O cache with a writer we do direct write
- cache to read cache copy. Do it before the write here so that
- the readers can work in parallel with the write.
- copy_to_read_buffer() relies on info->pos_in_file.
- */
- if (info->share)
- copy_to_read_buffer(info, info->write_buffer, length);
-
- pos_in_file=info->pos_in_file;
- /*
- If we have append cache, we always open the file with
- O_APPEND which moves the pos to EOF automatically on every write
- */
- if (!append_cache && info->seek_not_done)
- { /* File touched, do seek */
- if (mysql_file_seek(info->file, pos_in_file, MY_SEEK_SET, MYF(0)) ==
- MY_FILEPOS_ERROR)
- {
- UNLOCK_APPEND_BUFFER;
- DBUG_RETURN((info->error= -1));
- }
- if (!append_cache)
- info->seek_not_done=0;
- }
- if (!append_cache)
- info->pos_in_file+=length;
- info->write_end= (info->write_buffer+info->buffer_length-
- ((pos_in_file+length) & (IO_SIZE-1)));
-
- if (mysql_file_write(info->file,info->write_buffer,length,
- info->myflags | MY_NABP))
- info->error= -1;
- else
- info->error= 0;
- if (!append_cache)
- {
- set_if_bigger(info->end_of_file,(pos_in_file+length));
- }
- else
- {
- info->end_of_file+=(info->write_pos-info->append_read_pos);
- DBUG_ASSERT(info->end_of_file == mysql_file_tell(info->file, MYF(0)));
- }
-
- info->append_read_pos=info->write_pos=info->write_buffer;
- ++info->disk_writes;
- UNLOCK_APPEND_BUFFER;
- DBUG_RETURN(info->error);
- }
- }
-#ifdef HAVE_AIOWAIT
- else if (info->type != READ_NET)
- {
- my_aiowait(&info->aio_result); /* Wait for outstanding req */
- info->inited=0;
- }
-#endif
- UNLOCK_APPEND_BUFFER;
- DBUG_RETURN(0);
-}
-
-/*
- Free an IO_CACHE object
-
- SYNOPSOS
- end_io_cache()
- info IO_CACHE Handle to free
-
- NOTES
- It's currently safe to call this if one has called init_io_cache()
- on the 'info' object, even if init_io_cache() failed.
- This function is also safe to call twice with the same handle.
-
- RETURN
- 0 ok
- # Error
-*/
-
-int end_io_cache(IO_CACHE *info)
-{
- int error=0;
- IO_CACHE_CALLBACK pre_close;
- DBUG_ENTER("end_io_cache");
- DBUG_PRINT("enter",("cache: 0x%lx", (ulong) info));
-
- /*
- Every thread must call remove_io_thread(). The last one destroys
- the share elements.
- */
- DBUG_ASSERT(!info->share || !info->share->total_threads);
-
- if ((pre_close=info->pre_close))
- {
- (*pre_close)(info);
- info->pre_close= 0;
- }
- if (info->alloced_buffer)
- {
- info->alloced_buffer=0;
- if (info->file != -1) /* File doesn't exist */
- error= my_b_flush_io_cache(info,1);
- my_free(info->buffer);
- info->buffer=info->read_pos=(uchar*) 0;
- }
- if (info->type == SEQ_READ_APPEND)
- {
- /* Destroy allocated mutex */
- info->type= TYPE_NOT_SET;
- mysql_mutex_destroy(&info->append_buffer_lock);
- }
- DBUG_RETURN(error);
-} /* end_io_cache */
-
-
-/**********************************************************************
- Testing of MF_IOCACHE
-**********************************************************************/
-
-#ifdef MAIN
-
-#include <my_dir.h>
-
-void die(const char* fmt, ...)
-{
- va_list va_args;
- va_start(va_args,fmt);
- fprintf(stderr,"Error:");
- vfprintf(stderr, fmt,va_args);
- fprintf(stderr,", errno=%d\n", errno);
- exit(1);
-}
-
-int open_file(const char* fname, IO_CACHE* info, int cache_size)
-{
- int fd;
- if ((fd=my_open(fname,O_CREAT | O_RDWR,MYF(MY_WME))) < 0)
- die("Could not open %s", fname);
- if (init_io_cache(info, fd, cache_size, SEQ_READ_APPEND, 0,0,MYF(MY_WME)))
- die("failed in init_io_cache()");
- return fd;
-}
-
-void close_file(IO_CACHE* info)
-{
- end_io_cache(info);
- my_close(info->file, MYF(MY_WME));
-}
-
-int main(int argc, char** argv)
-{
- IO_CACHE sra_cache; /* SEQ_READ_APPEND */
- MY_STAT status;
- const char* fname="/tmp/iocache.test";
- int cache_size=16384;
- char llstr_buf[22];
- int max_block,total_bytes=0;
- int i,num_loops=100,error=0;
- char *p;
- char* block, *block_end;
- MY_INIT(argv[0]);
- max_block = cache_size*3;
- if (!(block=(char*)my_malloc(max_block,MYF(MY_WME))))
- die("Not enough memory to allocate test block");
- block_end = block + max_block;
- for (p = block,i=0; p < block_end;i++)
- {
- *p++ = (char)i;
- }
- if (my_stat(fname,&status, MYF(0)) &&
- my_delete(fname,MYF(MY_WME)))
- {
- die("Delete of %s failed, aborting", fname);
- }
- open_file(fname,&sra_cache, cache_size);
- for (i = 0; i < num_loops; i++)
- {
- char buf[4];
- int block_size = abs(rand() % max_block);
- int4store(buf, block_size);
- if (my_b_append(&sra_cache,buf,4) ||
- my_b_append(&sra_cache, block, block_size))
- die("write failed");
- total_bytes += 4+block_size;
- }
- close_file(&sra_cache);
- my_free(block);
- if (!my_stat(fname,&status,MYF(MY_WME)))
- die("%s failed to stat, but I had just closed it,\
- wonder how that happened");
- printf("Final size of %s is %s, wrote %d bytes\n",fname,
- llstr(status.st_size,llstr_buf),
- total_bytes);
- my_delete(fname, MYF(MY_WME));
- /* check correctness of tests */
- if (total_bytes != status.st_size)
- {
- fprintf(stderr,"Not the same number of bytes acutally in file as bytes \
-supposedly written\n");
- error=1;
- }
- exit(error);
- return 0;
-}
-#endif
diff --git a/dep/mysqllite/mysys/mf_iocache2.c b/dep/mysqllite/mysys/mf_iocache2.c
deleted file mode 100644
index 8962a037da0..00000000000
--- a/dep/mysqllite/mysys/mf_iocache2.c
+++ /dev/null
@@ -1,472 +0,0 @@
-/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 */
-
-/*
- More functions to be used with IO_CACHE files
-*/
-
-#include "mysys_priv.h"
-#include <m_string.h>
-#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)
-{
- size_t 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);
- do
- {
- if (my_fwrite(file, cache->read_pos, bytes_in_cache,
- MYF(MY_WME | MY_NABP)) == (size_t) -1)
- DBUG_RETURN(1);
- cache->read_pos= cache->read_end;
- } while ((bytes_in_cache= my_b_fill(cache)));
- DBUG_RETURN(0);
-}
-
-
-my_off_t my_b_append_tell(IO_CACHE* info)
-{
- /*
- Sometimes we want to make sure that the variable is not put into
- a register in debugging mode so we can see its value in the core
- */
-#ifndef DBUG_OFF
-# define dbug_volatile volatile
-#else
-# define dbug_volatile
-#endif
-
- /*
- Prevent optimizer from putting res in a register when debugging
- we need this to be able to see the value of res when the assert fails
- */
- dbug_volatile my_off_t res;
-
- /*
- We need to lock the append buffer mutex to keep flush_io_cache()
- from messing with the variables that we need in order to provide the
- answer to the question.
- */
- mysql_mutex_lock(&info->append_buffer_lock);
-
-#ifndef DBUG_OFF
- /*
- Make sure EOF is where we think it is. Note that we cannot just use
- my_tell() because we have a reader thread that could have left the
- file offset in a non-EOF location
- */
- {
- volatile my_off_t save_pos;
- save_pos = my_tell(info->file,MYF(0));
- my_seek(info->file,(my_off_t)0,MY_SEEK_END,MYF(0));
- /*
- Save the value of my_tell in res so we can see it when studying coredump
- */
- DBUG_ASSERT(info->end_of_file - (info->append_read_pos-info->write_buffer)
- == (res=my_tell(info->file,MYF(0))));
- my_seek(info->file,save_pos,MY_SEEK_SET,MYF(0));
- }
-#endif
- res = info->end_of_file + (info->write_pos-info->append_read_pos);
- mysql_mutex_unlock(&info->append_buffer_lock);
- return res;
-}
-
-my_off_t my_b_safe_tell(IO_CACHE *info)
-{
- if (unlikely(info->type == SEQ_READ_APPEND))
- return my_b_append_tell(info);
- return my_b_tell(info);
-}
-
-/*
- Make next read happen at the given position
- For write cache, make next write happen at the given position
-*/
-
-void my_b_seek(IO_CACHE *info,my_off_t pos)
-{
- my_off_t offset;
- DBUG_ENTER("my_b_seek");
- DBUG_PRINT("enter",("pos: %lu", (ulong) pos));
-
- /*
- TODO:
- Verify that it is OK to do seek in the non-append
- area in SEQ_READ_APPEND cache
- a) see if this always works
- b) see if there is a better way to make it work
- */
- if (info->type == SEQ_READ_APPEND)
- (void) flush_io_cache(info);
-
- offset=(pos - info->pos_in_file);
-
- if (info->type == READ_CACHE || info->type == SEQ_READ_APPEND)
- {
- /* TODO: explain why this works if pos < info->pos_in_file */
- if ((ulonglong) offset < (ulonglong) (info->read_end - info->buffer))
- {
- /* The read is in the current buffer; Reuse it */
- info->read_pos = info->buffer + offset;
- DBUG_VOID_RETURN;
- }
- else
- {
- /* Force a new read on next my_b_read */
- info->read_pos=info->read_end=info->buffer;
- }
- }
- else if (info->type == WRITE_CACHE)
- {
- /* If write is in current buffer, reuse it */
- if ((ulonglong) offset <
- (ulonglong) (info->write_end - info->write_buffer))
- {
- info->write_pos = info->write_buffer + offset;
- DBUG_VOID_RETURN;
- }
- (void) flush_io_cache(info);
- /* Correct buffer end so that we write in increments of IO_SIZE */
- info->write_end=(info->write_buffer+info->buffer_length-
- (pos & (IO_SIZE-1)));
- }
- info->pos_in_file=pos;
- info->seek_not_done=1;
- DBUG_VOID_RETURN;
-}
-
-
-/*
- Fill buffer of the cache.
-
- NOTES
- This assumes that you have already used all characters in the CACHE,
- independent of the read_pos value!
-
- RETURN
- 0 On error or EOF (info->error = -1 on error)
- # Number of characters
-*/
-
-
-size_t my_b_fill(IO_CACHE *info)
-{
- my_off_t pos_in_file=(info->pos_in_file+
- (size_t) (info->read_end - info->buffer));
- size_t diff_length, length, max_length;
-
- if (info->seek_not_done)
- { /* File touched, do seek */
- if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) ==
- MY_FILEPOS_ERROR)
- {
- info->error= 0;
- return 0;
- }
- info->seek_not_done=0;
- }
- diff_length=(size_t) (pos_in_file & (IO_SIZE-1));
- max_length=(info->read_length-diff_length);
- if (max_length >= (info->end_of_file - pos_in_file))
- max_length= (size_t) (info->end_of_file - pos_in_file);
-
- if (!max_length)
- {
- info->error= 0;
- return 0; /* EOF */
- }
- if ((length= my_read(info->file,info->buffer,max_length,
- info->myflags)) == (size_t) -1)
- {
- info->error= -1;
- return 0;
- }
- info->read_pos=info->buffer;
- info->read_end=info->buffer+length;
- info->pos_in_file=pos_in_file;
- return length;
-}
-
-
-/*
- Read a string ended by '\n' into a buffer of 'max_length' size.
- Returns number of characters read, 0 on error.
- last byte is set to '\0'
- If buffer is full then to[max_length-1] will be set to \0.
-*/
-
-size_t my_b_gets(IO_CACHE *info, char *to, size_t max_length)
-{
- char *start = to;
- size_t length;
- max_length--; /* Save place for end \0 */
-
- /* Calculate number of characters in buffer */
- if (!(length= my_b_bytes_in_cache(info)) &&
- !(length= my_b_fill(info)))
- return 0;
-
- for (;;)
- {
- uchar *pos, *end;
- if (length > max_length)
- length=max_length;
- for (pos=info->read_pos,end=pos+length ; pos < end ;)
- {
- if ((*to++ = *pos++) == '\n')
- {
- info->read_pos=pos;
- *to='\0';
- return (size_t) (to-start);
- }
- }
- if (!(max_length-=length))
- {
- /* Found enough charcters; Return found string */
- info->read_pos=pos;
- *to='\0';
- return (size_t) (to-start);
- }
- if (!(length=my_b_fill(info)))
- return 0;
- }
-}
-
-
-my_off_t my_b_filelength(IO_CACHE *info)
-{
- if (info->type == WRITE_CACHE)
- return my_b_tell(info);
-
- info->seek_not_done= 1;
- return my_seek(info->file, 0L, MY_SEEK_END, MYF(0));
-}
-
-
-/*
- Simple printf version. Supports '%s', '%d', '%u', "%ld" and "%lu"
- Used for logging in MySQL
- returns number of written character, or (size_t) -1 on error
-*/
-
-size_t my_b_printf(IO_CACHE *info, const char* fmt, ...)
-{
- size_t result;
- va_list args;
- va_start(args,fmt);
- result=my_b_vprintf(info, fmt, args);
- va_end(args);
- return result;
-}
-
-
-size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args)
-{
- size_t out_length= 0;
- uint minimum_width; /* as yet unimplemented */
- uint minimum_width_sign;
- uint precision; /* as yet unimplemented for anything but %b */
- my_bool is_zero_padded;
-
- /*
- Store the location of the beginning of a format directive, for the
- case where we learn we shouldn't have been parsing a format string
- at all, and we don't want to lose the flag/precision/width/size
- information.
- */
- const char* backtrack;
-
- for (; *fmt != '\0'; fmt++)
- {
- /* Copy everything until '%' or end of string */
- const char *start=fmt;
- size_t length;
-
- for (; (*fmt != '\0') && (*fmt != '%'); fmt++) ;
-
- length= (size_t) (fmt - start);
- out_length+=length;
- if (my_b_write(info, (const uchar*) start, length))
- goto err;
-
- if (*fmt == '\0') /* End of format */
- return out_length;
-
- /*
- By this point, *fmt must be a percent; Keep track of this location and
- skip over the percent character.
- */
- DBUG_ASSERT(*fmt == '%');
- backtrack= fmt;
- fmt++;
-
- is_zero_padded= FALSE;
- minimum_width_sign= 1;
- minimum_width= 0;
- precision= 0;
- /* Skip if max size is used (to be compatible with printf) */
-
-process_flags:
- switch (*fmt)
- {
- case '-':
- minimum_width_sign= -1; fmt++; goto process_flags;
- case '0':
- is_zero_padded= TRUE; fmt++; goto process_flags;
- case '#':
- /** @todo Implement "#" conversion flag. */ fmt++; goto process_flags;
- case ' ':
- /** @todo Implement " " conversion flag. */ fmt++; goto process_flags;
- case '+':
- /** @todo Implement "+" conversion flag. */ fmt++; goto process_flags;
- }
-
- if (*fmt == '*')
- {
- precision= (int) va_arg(args, int);
- fmt++;
- }
- else
- {
- while (my_isdigit(&my_charset_latin1, *fmt)) {
- minimum_width=(minimum_width * 10) + (*fmt - '0');
- fmt++;
- }
- }
- minimum_width*= minimum_width_sign;
-
- if (*fmt == '.')
- {
- fmt++;
- if (*fmt == '*') {
- precision= (int) va_arg(args, int);
- fmt++;
- }
- else
- {
- while (my_isdigit(&my_charset_latin1, *fmt)) {
- precision=(precision * 10) + (*fmt - '0');
- fmt++;
- }
- }
- }
-
- if (*fmt == 's') /* String parameter */
- {
- reg2 char *par = va_arg(args, char *);
- size_t length2 = strlen(par);
- /* TODO: implement precision */
- out_length+= length2;
- if (my_b_write(info, (uchar*) par, length2))
- goto err;
- }
- else if (*fmt == 'b') /* Sized buffer parameter, only precision makes sense */
- {
- char *par = va_arg(args, char *);
- out_length+= precision;
- if (my_b_write(info, (uchar*) par, precision))
- goto err;
- }
- else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
- {
- register int iarg;
- size_t length2;
- char buff[17];
-
- iarg = va_arg(args, int);
- if (*fmt == 'd')
- length2= (size_t) (int10_to_str((long) iarg,buff, -10) - buff);
- else
- length2= (uint) (int10_to_str((long) (uint) iarg,buff,10)- buff);
-
- /* minimum width padding */
- if (minimum_width > length2)
- {
- char *buffz;
-
- buffz= my_alloca(minimum_width - length2);
- if (is_zero_padded)
- memset(buffz, '0', minimum_width - length2);
- else
- memset(buffz, ' ', minimum_width - length2);
- my_b_write(info, buffz, minimum_width - length2);
- my_afree(buffz);
- }
-
- out_length+= length2;
- if (my_b_write(info, (uchar*) buff, length2))
- goto err;
- }
- else if ((*fmt == 'l' && fmt[1] == 'd') || fmt[1] == 'u')
- /* long parameter */
- {
- register long iarg;
- size_t length2;
- char buff[17];
-
- iarg = va_arg(args, long);
- if (*++fmt == 'd')
- length2= (size_t) (int10_to_str(iarg,buff, -10) - buff);
- else
- length2= (size_t) (int10_to_str(iarg,buff,10)- buff);
- out_length+= length2;
- if (my_b_write(info, (uchar*) buff, length2))
- goto err;
- }
- else
- {
- /* %% or unknown code */
- if (my_b_write(info, (uchar*) backtrack, (size_t) (fmt-backtrack)))
- goto err;
- out_length+= fmt-backtrack;
- }
- }
- return out_length;
-
-err:
- return (size_t) -1;
-}
diff --git a/dep/mysqllite/mysys/mf_keycache.c b/dep/mysqllite/mysys/mf_keycache.c
deleted file mode 100644
index 42cdea65f34..00000000000
--- a/dep/mysqllite/mysys/mf_keycache.c
+++ /dev/null
@@ -1,4523 +0,0 @@
-/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 */
-
-/**
- @file
- These functions handle keyblock cacheing for ISAM and MyISAM tables.
-
- One cache can handle many files.
- It must contain buffers of the same blocksize.
- init_key_cache() should be used to init cache handler.
-
- The free list (free_block_list) is a stack like structure.
- When a block is freed by free_block(), it is pushed onto the stack.
- When a new block is required it is first tried to pop one from the stack.
- If the stack is empty, it is tried to get a never-used block from the pool.
- If this is empty too, then a block is taken from the LRU ring, flushing it
- to disk, if neccessary. This is handled in find_key_block().
- With the new free list, the blocks can have three temperatures:
- hot, warm and cold (which is free). This is remembered in the block header
- by the enum BLOCK_TEMPERATURE temperature variable. Remembering the
- temperature is neccessary to correctly count the number of warm blocks,
- which is required to decide when blocks are allowed to become hot. Whenever
- a block is inserted to another (sub-)chain, we take the old and new
- temperature into account to decide if we got one more or less warm block.
- blocks_unused is the sum of never used blocks in the pool and of currently
- free blocks. blocks_used is the number of blocks fetched from the pool and
- as such gives the maximum number of in-use blocks at any time.
-*/
-
-/*
- Key Cache Locking
- =================
-
- All key cache locking is done with a single mutex per key cache:
- keycache->cache_lock. This mutex is locked almost all the time
- when executing code in this file (mf_keycache.c).
- However it is released for I/O and some copy operations.
-
- The cache_lock is also released when waiting for some event. Waiting
- and signalling is done via condition variables. In most cases the
- thread waits on its thread->suspend condition variable. Every thread
- has a my_thread_var structure, which contains this variable and a
- '*next' and '**prev' pointer. These pointers are used to insert the
- thread into a wait queue.
-
- A thread can wait for one block and thus be in one wait queue at a
- time only.
-
- Before starting to wait on its condition variable with
- mysql_cond_wait(), the thread enters itself to a specific wait queue
- with link_into_queue() (double linked with '*next' + '**prev') or
- wait_on_queue() (single linked with '*next').
-
- Another thread, when releasing a resource, looks up the waiting thread
- in the related wait queue. It sends a signal with
- mysql_cond_signal() to the waiting thread.
-
- NOTE: Depending on the particular wait situation, either the sending
- thread removes the waiting thread from the wait queue with
- unlink_from_queue() or release_whole_queue() respectively, or the waiting
- thread removes itself.
-
- There is one exception from this locking scheme when one thread wants
- to reuse a block for some other address. This works by first marking
- the block reserved (status= BLOCK_IN_SWITCH) and then waiting for all
- threads that are reading the block to finish. Each block has a
- reference to a condition variable (condvar). It holds a reference to
- the thread->suspend condition variable for the waiting thread (if such
- a thread exists). When that thread is signaled, the reference is
- cleared. The number of readers of a block is registered in
- block->hash_link->requests. See wait_for_readers() / remove_reader()
- for details. This is similar to the above, but it clearly means that
- only one thread can wait for a particular block. There is no queue in
- this case. Strangely enough block->convar is used for waiting for the
- assigned hash_link only. More precisely it is used to wait for all
- requests to be unregistered from the assigned hash_link.
-
- The resize_queue serves two purposes:
- 1. Threads that want to do a resize wait there if in_resize is set.
- This is not used in the server. The server refuses a second resize
- request if one is already active. keycache->in_init is used for the
- synchronization. See set_var.cc.
- 2. Threads that want to access blocks during resize wait here during
- the re-initialization phase.
- When the resize is done, all threads on the queue are signalled.
- Hypothetical resizers can compete for resizing, and read/write
- requests will restart to request blocks from the freshly resized
- cache. If the cache has been resized too small, it is disabled and
- 'can_be_used' is false. In this case read/write requests bypass the
- cache. Since they increment and decrement 'cnt_for_resize_op', the
- next resizer can wait on the queue 'waiting_for_resize_cnt' until all
- I/O finished.
-*/
-
-#include "mysys_priv.h"
-#include "mysys_err.h"
-#include <keycache.h>
-#include "my_static.h"
-#include <m_string.h>
-#include <my_bit.h>
-#include <errno.h>
-#include <stdarg.h>
-#include "probes_mysql.h"
-
-/*
- Some compilation flags have been added specifically for this module
- to control the following:
- - not to let a thread to yield the control when reading directly
- from key cache, which might improve performance in many cases;
- to enable this add:
- #define SERIALIZED_READ_FROM_CACHE
- - to set an upper bound for number of threads simultaneously
- using the key cache; this setting helps to determine an optimal
- size for hash table and improve performance when the number of
- blocks in the key cache much less than the number of threads
- accessing it;
- to set this number equal to <N> add
- #define MAX_THREADS <N>
- - to substitute calls of mysql_cond_wait for calls of
- mysql_cond_timedwait (wait with timeout set up);
- this setting should be used only when you want to trap a deadlock
- situation, which theoretically should not happen;
- to set timeout equal to <T> seconds add
- #define KEYCACHE_TIMEOUT <T>
- - to enable the module traps and to send debug information from
- key cache module to a special debug log add:
- #define KEYCACHE_DEBUG
- the name of this debug log file <LOG NAME> can be set through:
- #define KEYCACHE_DEBUG_LOG <LOG NAME>
- if the name is not defined, it's set by default;
- if the KEYCACHE_DEBUG flag is not set up and we are in a debug
- mode, i.e. when ! defined(DBUG_OFF), the debug information from the
- module is sent to the regular debug log.
-
- Example of the settings:
- #define SERIALIZED_READ_FROM_CACHE
- #define MAX_THREADS 100
- #define KEYCACHE_TIMEOUT 1
- #define KEYCACHE_DEBUG
- #define KEYCACHE_DEBUG_LOG "my_key_cache_debug.log"
-*/
-
-#define STRUCT_PTR(TYPE, MEMBER, a) \
- (TYPE *) ((char *) (a) - offsetof(TYPE, MEMBER))
-
-/* types of condition variables */
-#define COND_FOR_REQUESTED 0
-#define COND_FOR_SAVED 1
-#define COND_FOR_READERS 2
-
-typedef mysql_cond_t KEYCACHE_CONDVAR;
-
-/* descriptor of the page in the key cache block buffer */
-struct st_keycache_page
-{
- int file; /* file to which the page belongs to */
- my_off_t filepos; /* position of the page in the file */
-};
-
-/* element in the chain of a hash table bucket */
-struct st_hash_link
-{
- struct st_hash_link *next, **prev; /* to connect links in the same bucket */
- struct st_block_link *block; /* reference to the block for the page: */
- File file; /* from such a file */
- my_off_t diskpos; /* with such an offset */
- uint requests; /* number of requests for the page */
-};
-
-/* simple states of a block */
-#define BLOCK_ERROR 1 /* an error occured when performing file i/o */
-#define BLOCK_READ 2 /* file block is in the block buffer */
-#define BLOCK_IN_SWITCH 4 /* block is preparing to read new page */
-#define BLOCK_REASSIGNED 8 /* blk does not accept requests for old page */
-#define BLOCK_IN_FLUSH 16 /* block is selected for flush */
-#define BLOCK_CHANGED 32 /* block buffer contains a dirty page */
-#define BLOCK_IN_USE 64 /* block is not free */
-#define BLOCK_IN_EVICTION 128 /* block is selected for eviction */
-#define BLOCK_IN_FLUSHWRITE 256 /* block is in write to file */
-#define BLOCK_FOR_UPDATE 512 /* block is selected for buffer modification */
-
-/* page status, returned by find_key_block */
-#define PAGE_READ 0
-#define PAGE_TO_BE_READ 1
-#define PAGE_WAIT_TO_BE_READ 2
-
-/* block temperature determines in which (sub-)chain the block currently is */
-enum BLOCK_TEMPERATURE { BLOCK_COLD /*free*/ , BLOCK_WARM , BLOCK_HOT };
-
-/* key cache block */
-struct st_block_link
-{
- struct st_block_link
- *next_used, **prev_used; /* to connect links in the LRU chain (ring) */
- struct st_block_link
- *next_changed, **prev_changed; /* for lists of file dirty/clean blocks */
- struct st_hash_link *hash_link; /* backward ptr to referring hash_link */
- KEYCACHE_WQUEUE wqueue[2]; /* queues on waiting requests for new/old pages */
- uint requests; /* number of requests for the block */
- uchar *buffer; /* buffer for the block page */
- uint offset; /* beginning of modified data in the buffer */
- uint length; /* end of data in the buffer */
- uint status; /* state of the block */
- enum BLOCK_TEMPERATURE temperature; /* block temperature: cold, warm, hot */
- uint hits_left; /* number of hits left until promotion */
- ulonglong last_hit_time; /* timestamp of the last hit */
- KEYCACHE_CONDVAR *condvar; /* condition variable for 'no readers' event */
-};
-
-KEY_CACHE dflt_key_cache_var;
-KEY_CACHE *dflt_key_cache= &dflt_key_cache_var;
-
-#define FLUSH_CACHE 2000 /* sort this many blocks at once */
-
-static int flush_all_key_blocks(KEY_CACHE *keycache);
-
-static void wait_on_queue(KEYCACHE_WQUEUE *wqueue,
- mysql_mutex_t *mutex);
-static void release_whole_queue(KEYCACHE_WQUEUE *wqueue);
-
-static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block);
-#if !defined(DBUG_OFF)
-static void test_key_cache(KEY_CACHE *keycache,
- const char *where, my_bool lock);
-#endif
-
-#define KEYCACHE_HASH(f, pos) \
-(((ulong) ((pos) / keycache->key_cache_block_size) + \
- (ulong) (f)) & (keycache->hash_entries-1))
-#define FILE_HASH(f) ((uint) (f) & (CHANGED_BLOCKS_HASH-1))
-
-#define DEFAULT_KEYCACHE_DEBUG_LOG "keycache_debug.log"
-
-#if defined(KEYCACHE_DEBUG) && ! defined(KEYCACHE_DEBUG_LOG)
-#define KEYCACHE_DEBUG_LOG DEFAULT_KEYCACHE_DEBUG_LOG
-#endif
-
-#if defined(KEYCACHE_DEBUG_LOG)
-static FILE *keycache_debug_log=NULL;
-static void keycache_debug_print(const char *fmt,...);
-#define KEYCACHE_DEBUG_OPEN \
- if (!keycache_debug_log) \
- { \
- keycache_debug_log= fopen(KEYCACHE_DEBUG_LOG, "w"); \
- (void) setvbuf(keycache_debug_log, NULL, _IOLBF, BUFSIZ); \
- }
-
-#define KEYCACHE_DEBUG_CLOSE \
- if (keycache_debug_log) \
- { \
- fclose(keycache_debug_log); \
- keycache_debug_log= 0; \
- }
-#else
-#define KEYCACHE_DEBUG_OPEN
-#define KEYCACHE_DEBUG_CLOSE
-#endif /* defined(KEYCACHE_DEBUG_LOG) */
-
-#if defined(KEYCACHE_DEBUG_LOG) && defined(KEYCACHE_DEBUG)
-#define KEYCACHE_DBUG_PRINT(l, m) \
- { if (keycache_debug_log) fprintf(keycache_debug_log, "%s: ", l); \
- keycache_debug_print m; }
-
-#define KEYCACHE_DBUG_ASSERT(a) \
- { if (! (a) && keycache_debug_log) fclose(keycache_debug_log); \
- assert(a); }
-#else
-#define KEYCACHE_DBUG_PRINT(l, m) DBUG_PRINT(l, m)
-#define KEYCACHE_DBUG_ASSERT(a) DBUG_ASSERT(a)
-#endif /* defined(KEYCACHE_DEBUG_LOG) && defined(KEYCACHE_DEBUG) */
-
-#if defined(KEYCACHE_DEBUG) || !defined(DBUG_OFF)
-
-static long keycache_thread_id;
-#define KEYCACHE_THREAD_TRACE(l) \
- KEYCACHE_DBUG_PRINT(l,("|thread %ld",keycache_thread_id))
-
-#define KEYCACHE_THREAD_TRACE_BEGIN(l) \
- { struct st_my_thread_var *thread_var= my_thread_var; \
- keycache_thread_id= thread_var->id; \
- KEYCACHE_DBUG_PRINT(l,("[thread %ld",keycache_thread_id)) }
-
-#define KEYCACHE_THREAD_TRACE_END(l) \
- KEYCACHE_DBUG_PRINT(l,("]thread %ld",keycache_thread_id))
-#else
-#define KEYCACHE_THREAD_TRACE_BEGIN(l)
-#define KEYCACHE_THREAD_TRACE_END(l)
-#define KEYCACHE_THREAD_TRACE(l)
-#endif /* defined(KEYCACHE_DEBUG) || !defined(DBUG_OFF) */
-
-#define BLOCK_NUMBER(b) \
- ((uint) (((char*)(b)-(char *) keycache->block_root)/sizeof(BLOCK_LINK)))
-#define HASH_LINK_NUMBER(h) \
- ((uint) (((char*)(h)-(char *) keycache->hash_link_root)/sizeof(HASH_LINK)))
-
-#if (defined(KEYCACHE_TIMEOUT) && !defined(__WIN__)) || defined(KEYCACHE_DEBUG)
-static int keycache_pthread_cond_wait(mysql_cond_t *cond,
- mysql_mutex_t *mutex);
-#else
-#define keycache_pthread_cond_wait(C, M) mysql_cond_wait(C, M)
-#endif
-
-#if defined(KEYCACHE_DEBUG)
-static int keycache_pthread_mutex_lock(mysql_mutex_t *mutex);
-static void keycache_pthread_mutex_unlock(mysql_mutex_t *mutex);
-static int keycache_pthread_cond_signal(mysql_cond_t *cond);
-#else
-#define keycache_pthread_mutex_lock(M) mysql_mutex_lock(M)
-#define keycache_pthread_mutex_unlock(M) mysql_mutex_unlock(M)
-#define keycache_pthread_cond_signal(C) mysql_cond_signal(C)
-#endif /* defined(KEYCACHE_DEBUG) */
-
-#if !defined(DBUG_OFF)
-#if defined(inline)
-#undef inline
-#endif
-#define inline /* disabled inline for easier debugging */
-static int fail_block(BLOCK_LINK *block);
-static int fail_hlink(HASH_LINK *hlink);
-static int cache_empty(KEY_CACHE *keycache);
-#endif
-
-static inline uint next_power(uint value)
-{
- return (uint) my_round_up_to_next_power((uint32) value) << 1;
-}
-
-
-/*
- Initialize a key cache
-
- SYNOPSIS
- init_key_cache()
- keycache pointer to a key cache data structure
- key_cache_block_size size of blocks to keep cached data
- use_mem total memory to use for the key cache
- division_limit division limit (may be zero)
- age_threshold age threshold (may be zero)
-
- RETURN VALUE
- number of blocks in the key cache, if successful,
- 0 - otherwise.
-
- NOTES.
- if keycache->key_cache_inited != 0 we assume that the key cache
- is already initialized. This is for now used by myisamchk, but shouldn't
- be something that a program should rely on!
-
- It's assumed that no two threads call this function simultaneously
- referring to the same key cache handle.
-
-*/
-
-int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
- size_t use_mem, uint division_limit,
- uint age_threshold)
-{
- ulong blocks, hash_links;
- size_t length;
- int error;
- DBUG_ENTER("init_key_cache");
- DBUG_ASSERT(key_cache_block_size >= 512);
-
- KEYCACHE_DEBUG_OPEN;
- if (keycache->key_cache_inited && keycache->disk_blocks > 0)
- {
- DBUG_PRINT("warning",("key cache already in use"));
- DBUG_RETURN(0);
- }
-
- keycache->global_cache_w_requests= keycache->global_cache_r_requests= 0;
- keycache->global_cache_read= keycache->global_cache_write= 0;
- keycache->disk_blocks= -1;
- if (! keycache->key_cache_inited)
- {
- keycache->key_cache_inited= 1;
- /*
- Initialize these variables once only.
- Their value must survive re-initialization during resizing.
- */
- keycache->in_resize= 0;
- keycache->resize_in_flush= 0;
- keycache->cnt_for_resize_op= 0;
- keycache->waiting_for_resize_cnt.last_thread= NULL;
- keycache->in_init= 0;
- mysql_mutex_init(key_KEY_CACHE_cache_lock,
- &keycache->cache_lock, MY_MUTEX_INIT_FAST);
- keycache->resize_queue.last_thread= NULL;
- }
-
- keycache->key_cache_mem_size= use_mem;
- keycache->key_cache_block_size= key_cache_block_size;
- DBUG_PRINT("info", ("key_cache_block_size: %u",
- key_cache_block_size));
-
- blocks= (ulong) (use_mem / (sizeof(BLOCK_LINK) + 2 * sizeof(HASH_LINK) +
- sizeof(HASH_LINK*) * 5/4 + key_cache_block_size));
- /* It doesn't make sense to have too few blocks (less than 8) */
- if (blocks >= 8)
- {
- for ( ; ; )
- {
- /* Set my_hash_entries to the next bigger 2 power */
- if ((keycache->hash_entries= next_power(blocks)) < blocks * 5/4)
- keycache->hash_entries<<= 1;
- hash_links= 2 * blocks;
-#if defined(MAX_THREADS)
- if (hash_links < MAX_THREADS + blocks - 1)
- hash_links= MAX_THREADS + blocks - 1;
-#endif
- while ((length= (ALIGN_SIZE(blocks * sizeof(BLOCK_LINK)) +
- ALIGN_SIZE(hash_links * sizeof(HASH_LINK)) +
- ALIGN_SIZE(sizeof(HASH_LINK*) *
- keycache->hash_entries))) +
- ((size_t) blocks * keycache->key_cache_block_size) > use_mem)
- blocks--;
- /* Allocate memory for cache page buffers */
- if ((keycache->block_mem=
- my_large_malloc((size_t) blocks * keycache->key_cache_block_size,
- MYF(0))))
- {
- /*
- Allocate memory for blocks, hash_links and hash entries;
- For each block 2 hash links are allocated
- */
- if ((keycache->block_root= (BLOCK_LINK*) my_malloc(length,
- MYF(0))))
- break;
- my_large_free(keycache->block_mem);
- keycache->block_mem= 0;
- }
- if (blocks < 8)
- {
- my_errno= ENOMEM;
- my_error(EE_OUTOFMEMORY, MYF(0), blocks * keycache->key_cache_block_size);
- goto err;
- }
- blocks= blocks / 4*3;
- }
- keycache->blocks_unused= blocks;
- keycache->disk_blocks= (int) blocks;
- keycache->hash_links= hash_links;
- keycache->hash_root= (HASH_LINK**) ((char*) keycache->block_root +
- ALIGN_SIZE(blocks*sizeof(BLOCK_LINK)));
- keycache->hash_link_root= (HASH_LINK*) ((char*) keycache->hash_root +
- ALIGN_SIZE((sizeof(HASH_LINK*) *
- keycache->hash_entries)));
- bzero((uchar*) keycache->block_root,
- keycache->disk_blocks * sizeof(BLOCK_LINK));
- bzero((uchar*) keycache->hash_root,
- keycache->hash_entries * sizeof(HASH_LINK*));
- bzero((uchar*) keycache->hash_link_root,
- keycache->hash_links * sizeof(HASH_LINK));
- keycache->hash_links_used= 0;
- keycache->free_hash_list= NULL;
- keycache->blocks_used= keycache->blocks_changed= 0;
-
- keycache->global_blocks_changed= 0;
- keycache->blocks_available=0; /* For debugging */
-
- /* The LRU chain is empty after initialization */
- keycache->used_last= NULL;
- keycache->used_ins= NULL;
- keycache->free_block_list= NULL;
- keycache->keycache_time= 0;
- keycache->warm_blocks= 0;
- keycache->min_warm_blocks= (division_limit ?
- blocks * division_limit / 100 + 1 :
- blocks);
- keycache->age_threshold= (age_threshold ?
- blocks * age_threshold / 100 :
- blocks);
-
- keycache->can_be_used= 1;
-
- keycache->waiting_for_hash_link.last_thread= NULL;
- keycache->waiting_for_block.last_thread= NULL;
- DBUG_PRINT("exit",
- ("disk_blocks: %d block_root: 0x%lx hash_entries: %d\
- hash_root: 0x%lx hash_links: %d hash_link_root: 0x%lx",
- keycache->disk_blocks, (long) keycache->block_root,
- keycache->hash_entries, (long) keycache->hash_root,
- keycache->hash_links, (long) keycache->hash_link_root));
- bzero((uchar*) keycache->changed_blocks,
- sizeof(keycache->changed_blocks[0]) * CHANGED_BLOCKS_HASH);
- bzero((uchar*) keycache->file_blocks,
- sizeof(keycache->file_blocks[0]) * CHANGED_BLOCKS_HASH);
- }
- else
- {
- /* key_buffer_size is specified too small. Disable the cache. */
- keycache->can_be_used= 0;
- }
-
- keycache->blocks= keycache->disk_blocks > 0 ? keycache->disk_blocks : 0;
- DBUG_RETURN((int) keycache->disk_blocks);
-
-err:
- error= my_errno;
- keycache->disk_blocks= 0;
- keycache->blocks= 0;
- if (keycache->block_mem)
- {
- my_large_free((uchar*) keycache->block_mem);
- keycache->block_mem= NULL;
- }
- if (keycache->block_root)
- {
- my_free(keycache->block_root);
- keycache->block_root= NULL;
- }
- my_errno= error;
- keycache->can_be_used= 0;
- DBUG_RETURN(0);
-}
-
-
-/*
- Resize a key cache
-
- SYNOPSIS
- resize_key_cache()
- keycache pointer to a key cache data structure
- key_cache_block_size size of blocks to keep cached data
- use_mem total memory to use for the new key cache
- division_limit new division limit (if not zero)
- age_threshold new age threshold (if not zero)
-
- RETURN VALUE
- number of blocks in the key cache, if successful,
- 0 - otherwise.
-
- NOTES.
- The function first compares the memory size and the block size parameters
- with the key cache values.
-
- If they differ the function free the the memory allocated for the
- old key cache blocks by calling the end_key_cache function and
- then rebuilds the key cache with new blocks by calling
- init_key_cache.
-
- The function starts the operation only when all other threads
- performing operations with the key cache let her to proceed
- (when cnt_for_resize=0).
-*/
-
-int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
- size_t use_mem, uint division_limit,
- uint age_threshold)
-{
- int blocks;
- DBUG_ENTER("resize_key_cache");
-
- if (!keycache->key_cache_inited)
- DBUG_RETURN(keycache->disk_blocks);
-
- if(key_cache_block_size == keycache->key_cache_block_size &&
- use_mem == keycache->key_cache_mem_size)
- {
- change_key_cache_param(keycache, division_limit, age_threshold);
- DBUG_RETURN(keycache->disk_blocks);
- }
-
- keycache_pthread_mutex_lock(&keycache->cache_lock);
-
- /*
- We may need to wait for another thread which is doing a resize
- already. This cannot happen in the MySQL server though. It allows
- one resizer only. In set_var.cc keycache->in_init is used to block
- multiple attempts.
- */
- while (keycache->in_resize)
- {
- /* purecov: begin inspected */
- wait_on_queue(&keycache->resize_queue, &keycache->cache_lock);
- /* purecov: end */
- }
-
- /*
- Mark the operation in progress. This blocks other threads from doing
- a resize in parallel. It prohibits new blocks to enter the cache.
- Read/write requests can bypass the cache during the flush phase.
- */
- keycache->in_resize= 1;
-
- /* Need to flush only if keycache is enabled. */
- if (keycache->can_be_used)
- {
- /* Start the flush phase. */
- keycache->resize_in_flush= 1;
-
- if (flush_all_key_blocks(keycache))
- {
- /* TODO: if this happens, we should write a warning in the log file ! */
- keycache->resize_in_flush= 0;
- blocks= 0;
- keycache->can_be_used= 0;
- goto finish;
- }
- DBUG_ASSERT(cache_empty(keycache));
-
- /* End the flush phase. */
- keycache->resize_in_flush= 0;
- }
-
- /*
- Some direct read/write operations (bypassing the cache) may still be
- unfinished. Wait until they are done. If the key cache can be used,
- direct I/O is done in increments of key_cache_block_size. That is,
- every block is checked if it is in the cache. We need to wait for
- pending I/O before re-initializing the cache, because we may change
- the block size. Otherwise they could check for blocks at file
- positions where the new block division has none. We do also want to
- wait for I/O done when (if) the cache was disabled. It must not
- run in parallel with normal cache operation.
- */
- while (keycache->cnt_for_resize_op)
- wait_on_queue(&keycache->waiting_for_resize_cnt, &keycache->cache_lock);
-
- /*
- Free old cache structures, allocate new structures, and initialize
- them. Note that the cache_lock mutex and the resize_queue are left
- untouched. We do not lose the cache_lock and will release it only at
- the end of this function.
- */
- end_key_cache(keycache, 0); /* Don't free mutex */
- /* The following will work even if use_mem is 0 */
- blocks= init_key_cache(keycache, key_cache_block_size, use_mem,
- division_limit, age_threshold);
-
-finish:
- /*
- Mark the resize finished. This allows other threads to start a
- resize or to request new cache blocks.
- */
- keycache->in_resize= 0;
-
- /* Signal waiting threads. */
- release_whole_queue(&keycache->resize_queue);
-
- keycache_pthread_mutex_unlock(&keycache->cache_lock);
- DBUG_RETURN(blocks);
-}
-
-
-/*
- Increment counter blocking resize key cache operation
-*/
-static inline void inc_counter_for_resize_op(KEY_CACHE *keycache)
-{
- keycache->cnt_for_resize_op++;
-}
-
-
-/*
- Decrement counter blocking resize key cache operation;
- Signal the operation to proceed when counter becomes equal zero
-*/
-static inline void dec_counter_for_resize_op(KEY_CACHE *keycache)
-{
- if (!--keycache->cnt_for_resize_op)
- release_whole_queue(&keycache->waiting_for_resize_cnt);
-}
-
-/*
- Change the key cache parameters
-
- SYNOPSIS
- change_key_cache_param()
- keycache pointer to a key cache data structure
- division_limit new division limit (if not zero)
- age_threshold new age threshold (if not zero)
-
- RETURN VALUE
- none
-
- NOTES.
- Presently the function resets the key cache parameters
- concerning midpoint insertion strategy - division_limit and
- age_threshold.
-*/
-
-void change_key_cache_param(KEY_CACHE *keycache, uint division_limit,
- uint age_threshold)
-{
- DBUG_ENTER("change_key_cache_param");
-
- keycache_pthread_mutex_lock(&keycache->cache_lock);
- if (division_limit)
- keycache->min_warm_blocks= (keycache->disk_blocks *
- division_limit / 100 + 1);
- if (age_threshold)
- keycache->age_threshold= (keycache->disk_blocks *
- age_threshold / 100);
- keycache_pthread_mutex_unlock(&keycache->cache_lock);
- DBUG_VOID_RETURN;
-}
-
-
-/*
- Remove key_cache from memory
-
- SYNOPSIS
- end_key_cache()
- keycache key cache handle
- cleanup Complete free (Free also mutex for key cache)
-
- RETURN VALUE
- none
-*/
-
-void end_key_cache(KEY_CACHE *keycache, my_bool cleanup)
-{
- DBUG_ENTER("end_key_cache");
- DBUG_PRINT("enter", ("key_cache: 0x%lx", (long) keycache));
-
- if (!keycache->key_cache_inited)
- DBUG_VOID_RETURN;
-
- if (keycache->disk_blocks > 0)
- {
- if (keycache->block_mem)
- {
- my_large_free((uchar*) keycache->block_mem);
- keycache->block_mem= NULL;
- my_free(keycache->block_root);
- keycache->block_root= NULL;
- }
- keycache->disk_blocks= -1;
- /* Reset blocks_changed to be safe if flush_all_key_blocks is called */
- keycache->blocks_changed= 0;
- }
-
- DBUG_PRINT("status", ("used: %lu changed: %lu w_requests: %lu "
- "writes: %lu r_requests: %lu reads: %lu",
- keycache->blocks_used, keycache->global_blocks_changed,
- (ulong) keycache->global_cache_w_requests,
- (ulong) keycache->global_cache_write,
- (ulong) keycache->global_cache_r_requests,
- (ulong) keycache->global_cache_read));
-
- /*
- Reset these values to be able to detect a disabled key cache.
- See Bug#44068 (RESTORE can disable the MyISAM Key Cache).
- */
- keycache->blocks_used= 0;
- keycache->blocks_unused= 0;
-
- if (cleanup)
- {
- mysql_mutex_destroy(&keycache->cache_lock);
- keycache->key_cache_inited= keycache->can_be_used= 0;
- KEYCACHE_DEBUG_CLOSE;
- }
- DBUG_VOID_RETURN;
-} /* end_key_cache */
-
-
-/*
- Link a thread into double-linked queue of waiting threads.
-
- SYNOPSIS
- link_into_queue()
- wqueue pointer to the queue structure
- thread pointer to the thread to be added to the queue
-
- RETURN VALUE
- none
-
- NOTES.
- Queue is represented by a circular list of the thread structures
- The list is double-linked of the type (**prev,*next), accessed by
- a pointer to the last element.
-*/
-
-static void link_into_queue(KEYCACHE_WQUEUE *wqueue,
- struct st_my_thread_var *thread)
-{
- struct st_my_thread_var *last;
-
- DBUG_ASSERT(!thread->next && !thread->prev);
- if (! (last= wqueue->last_thread))
- {
- /* Queue is empty */
- thread->next= thread;
- thread->prev= &thread->next;
- }
- else
- {
- thread->prev= last->next->prev;
- last->next->prev= &thread->next;
- thread->next= last->next;
- last->next= thread;
- }
- wqueue->last_thread= thread;
-}
-
-/*
- Unlink a thread from double-linked queue of waiting threads
-
- SYNOPSIS
- unlink_from_queue()
- wqueue pointer to the queue structure
- thread pointer to the thread to be removed from the queue
-
- RETURN VALUE
- none
-
- NOTES.
- See NOTES for link_into_queue
-*/
-
-static void unlink_from_queue(KEYCACHE_WQUEUE *wqueue,
- struct st_my_thread_var *thread)
-{
- KEYCACHE_DBUG_PRINT("unlink_from_queue", ("thread %ld", thread->id));
- DBUG_ASSERT(thread->next && thread->prev);
- if (thread->next == thread)
- /* The queue contains only one member */
- wqueue->last_thread= NULL;
- else
- {
- thread->next->prev= thread->prev;
- *thread->prev=thread->next;
- if (wqueue->last_thread == thread)
- wqueue->last_thread= STRUCT_PTR(struct st_my_thread_var, next,
- thread->prev);
- }
- thread->next= NULL;
-#if !defined(DBUG_OFF)
- /*
- This makes it easier to see it's not in a chain during debugging.
- And some DBUG_ASSERT() rely on it.
- */
- thread->prev= NULL;
-#endif
-}
-
-
-/*
- Add a thread to single-linked queue of waiting threads
-
- SYNOPSIS
- wait_on_queue()
- wqueue Pointer to the queue structure.
- mutex Cache_lock to acquire after awake.
-
- RETURN VALUE
- none
-
- NOTES.
- Queue is represented by a circular list of the thread structures
- The list is single-linked of the type (*next), accessed by a pointer
- to the last element.
-
- The function protects against stray signals by verifying that the
- current thread is unlinked from the queue when awaking. However,
- since several threads can wait for the same event, it might be
- necessary for the caller of the function to check again if the
- condition for awake is indeed matched.
-*/
-
-static void wait_on_queue(KEYCACHE_WQUEUE *wqueue,
- mysql_mutex_t *mutex)
-{
- struct st_my_thread_var *last;
- struct st_my_thread_var *thread= my_thread_var;
-
- /* Add to queue. */
- DBUG_ASSERT(!thread->next);
- DBUG_ASSERT(!thread->prev); /* Not required, but must be true anyway. */
- if (! (last= wqueue->last_thread))
- thread->next= thread;
- else
- {
- thread->next= last->next;
- last->next= thread;
- }
- wqueue->last_thread= thread;
-
- /*
- Wait until thread is removed from queue by the signalling thread.
- The loop protects against stray signals.
- */
- do
- {
- KEYCACHE_DBUG_PRINT("wait", ("suspend thread %ld", thread->id));
- keycache_pthread_cond_wait(&thread->suspend, mutex);
- }
- while (thread->next);
-}
-
-
-/*
- Remove all threads from queue signaling them to proceed
-
- SYNOPSIS
- release_whole_queue()
- wqueue pointer to the queue structure
-
- RETURN VALUE
- none
-
- NOTES.
- See notes for wait_on_queue().
- When removed from the queue each thread is signaled via condition
- variable thread->suspend.
-*/
-
-static void release_whole_queue(KEYCACHE_WQUEUE *wqueue)
-{
- struct st_my_thread_var *last;
- struct st_my_thread_var *next;
- struct st_my_thread_var *thread;
-
- /* Queue may be empty. */
- if (!(last= wqueue->last_thread))
- return;
-
- next= last->next;
- do
- {
- thread=next;
- KEYCACHE_DBUG_PRINT("release_whole_queue: signal",
- ("thread %ld", thread->id));
- /* Signal the thread. */
- keycache_pthread_cond_signal(&thread->suspend);
- /* Take thread from queue. */
- next=thread->next;
- thread->next= NULL;
- }
- while (thread != last);
-
- /* Now queue is definitely empty. */
- wqueue->last_thread= NULL;
-}
-
-
-/*
- Unlink a block from the chain of dirty/clean blocks
-*/
-
-static inline void unlink_changed(BLOCK_LINK *block)
-{
- DBUG_ASSERT(block->prev_changed && *block->prev_changed == block);
- if (block->next_changed)
- block->next_changed->prev_changed= block->prev_changed;
- *block->prev_changed= block->next_changed;
-
-#if !defined(DBUG_OFF)
- /*
- This makes it easier to see it's not in a chain during debugging.
- And some DBUG_ASSERT() rely on it.
- */
- block->next_changed= NULL;
- block->prev_changed= NULL;
-#endif
-}
-
-
-/*
- Link a block into the chain of dirty/clean blocks
-*/
-
-static inline void link_changed(BLOCK_LINK *block, BLOCK_LINK **phead)
-{
- DBUG_ASSERT(!block->next_changed);
- DBUG_ASSERT(!block->prev_changed);
- block->prev_changed= phead;
- if ((block->next_changed= *phead))
- (*phead)->prev_changed= &block->next_changed;
- *phead= block;
-}
-
-
-/*
- Link a block in a chain of clean blocks of a file.
-
- SYNOPSIS
- link_to_file_list()
- keycache Key cache handle
- block Block to relink
- file File to be linked to
- unlink If to unlink first
-
- DESCRIPTION
- Unlink a block from whichever chain it is linked in, if it's
- asked for, and link it to the chain of clean blocks of the
- specified file.
-
- NOTE
- Please do never set/clear BLOCK_CHANGED outside of
- link_to_file_list() or link_to_changed_list().
- You would risk to damage correct counting of changed blocks
- and to find blocks in the wrong hash.
-
- RETURN
- void
-*/
-
-static void link_to_file_list(KEY_CACHE *keycache,
- BLOCK_LINK *block, int file,
- my_bool unlink_block)
-{
- DBUG_ASSERT(block->status & BLOCK_IN_USE);
- DBUG_ASSERT(block->hash_link && block->hash_link->block == block);
- DBUG_ASSERT(block->hash_link->file == file);
- if (unlink_block)
- unlink_changed(block);
- link_changed(block, &keycache->file_blocks[FILE_HASH(file)]);
- if (block->status & BLOCK_CHANGED)
- {
- block->status&= ~BLOCK_CHANGED;
- keycache->blocks_changed--;
- keycache->global_blocks_changed--;
- }
-}
-
-
-/*
- Re-link a block from the clean chain to the dirty chain of a file.
-
- SYNOPSIS
- link_to_changed_list()
- keycache key cache handle
- block block to relink
-
- DESCRIPTION
- Unlink a block from the chain of clean blocks of a file
- and link it to the chain of dirty blocks of the same file.
-
- NOTE
- Please do never set/clear BLOCK_CHANGED outside of
- link_to_file_list() or link_to_changed_list().
- You would risk to damage correct counting of changed blocks
- and to find blocks in the wrong hash.
-
- RETURN
- void
-*/
-
-static void link_to_changed_list(KEY_CACHE *keycache,
- BLOCK_LINK *block)
-{
- DBUG_ASSERT(block->status & BLOCK_IN_USE);
- DBUG_ASSERT(!(block->status & BLOCK_CHANGED));
- DBUG_ASSERT(block->hash_link && block->hash_link->block == block);
-
- unlink_changed(block);
- link_changed(block,
- &keycache->changed_blocks[FILE_HASH(block->hash_link->file)]);
- block->status|=BLOCK_CHANGED;
- keycache->blocks_changed++;
- keycache->global_blocks_changed++;
-}
-
-
-/*
- Link a block to the LRU chain at the beginning or at the end of
- one of two parts.
-
- SYNOPSIS
- link_block()
- keycache pointer to a key cache data structure
- block pointer to the block to link to the LRU chain
- hot <-> to link the block into the hot subchain
- at_end <-> to link the block at the end of the subchain
-
- RETURN VALUE
- none
-
- NOTES.
- The LRU ring is represented by a circular list of block structures.
- The list is double-linked of the type (**prev,*next) type.
- The LRU ring is divided into two parts - hot and warm.
- There are two pointers to access the last blocks of these two
- parts. The beginning of the warm part follows right after the
- end of the hot part.
- Only blocks of the warm part can be used for eviction.
- The first block from the beginning of this subchain is always
- taken for eviction (keycache->last_used->next)
-
- LRU chain: +------+ H O T +------+
- +----| end |----...<----| beg |----+
- | +------+last +------+ |
- v<-link in latest hot (new end) |
- | link in latest warm (new end)->^
- | +------+ W A R M +------+ |
- +----| beg |---->...----| end |----+
- +------+ +------+ins
- first for eviction
-
- It is also possible that the block is selected for eviction and thus
- not linked in the LRU ring.
-*/
-
-static void link_block(KEY_CACHE *keycache, BLOCK_LINK *block, my_bool hot,
- my_bool at_end)
-{
- BLOCK_LINK *ins;
- BLOCK_LINK **pins;
-
- DBUG_ASSERT((block->status & ~BLOCK_CHANGED) == (BLOCK_READ | BLOCK_IN_USE));
- DBUG_ASSERT(block->hash_link); /*backptr to block NULL from free_block()*/
- DBUG_ASSERT(!block->requests);
- DBUG_ASSERT(block->prev_changed && *block->prev_changed == block);
- DBUG_ASSERT(!block->next_used);
- DBUG_ASSERT(!block->prev_used);
-
- if (!hot && keycache->waiting_for_block.last_thread)
- {
- /* Signal that in the LRU warm sub-chain an available block has appeared */
- struct st_my_thread_var *last_thread=
- keycache->waiting_for_block.last_thread;
- struct st_my_thread_var *first_thread= last_thread->next;
- struct st_my_thread_var *next_thread= first_thread;
- HASH_LINK *hash_link= (HASH_LINK *) first_thread->opt_info;
- struct st_my_thread_var *thread;
- do
- {
- thread= next_thread;
- next_thread= thread->next;
- /*
- We notify about the event all threads that ask
- for the same page as the first thread in the queue
- */
- if ((HASH_LINK *) thread->opt_info == hash_link)
- {
- KEYCACHE_DBUG_PRINT("link_block: signal", ("thread %ld", thread->id));
- keycache_pthread_cond_signal(&thread->suspend);
- unlink_from_queue(&keycache->waiting_for_block, thread);
- block->requests++;
- }
- }
- while (thread != last_thread);
- hash_link->block= block;
- /*
- NOTE: We assigned the block to the hash_link and signalled the
- requesting thread(s). But it is possible that other threads runs
- first. These threads see the hash_link assigned to a block which
- is assigned to another hash_link and not marked BLOCK_IN_SWITCH.
- This can be a problem for functions that do not select the block
- via its hash_link: flush and free. They do only see a block which
- is in a "normal" state and don't know that it will be evicted soon.
-
- We cannot set BLOCK_IN_SWITCH here because only one of the
- requesting threads must handle the eviction. All others must wait
- for it to complete. If we set the flag here, the threads would not
- know who is in charge of the eviction. Without the flag, the first
- thread takes the stick and sets the flag.
-
- But we need to note in the block that is has been selected for
- eviction. It must not be freed. The evicting thread will not
- expect the block in the free list. Before freeing we could also
- check if block->requests > 1. But I think including another flag
- in the check of block->status is slightly more efficient and
- probably easier to read.
- */
- block->status|= BLOCK_IN_EVICTION;
- KEYCACHE_THREAD_TRACE("link_block: after signaling");
-#if defined(KEYCACHE_DEBUG)
- KEYCACHE_DBUG_PRINT("link_block",
- ("linked,unlinked block %u status=%x #requests=%u #available=%u",
- BLOCK_NUMBER(block), block->status,
- block->requests, keycache->blocks_available));
-#endif
- return;
- }
-
- pins= hot ? &keycache->used_ins : &keycache->used_last;
- ins= *pins;
- if (ins)
- {
- ins->next_used->prev_used= &block->next_used;
- block->next_used= ins->next_used;
- block->prev_used= &ins->next_used;
- ins->next_used= block;
- if (at_end)
- *pins= block;
- }
- else
- {
- /* The LRU ring is empty. Let the block point to itself. */
- keycache->used_last= keycache->used_ins= block->next_used= block;
- block->prev_used= &block->next_used;
- }
- KEYCACHE_THREAD_TRACE("link_block");
-#if defined(KEYCACHE_DEBUG)
- keycache->blocks_available++;
- KEYCACHE_DBUG_PRINT("link_block",
- ("linked block %u:%1u status=%x #requests=%u #available=%u",
- BLOCK_NUMBER(block), at_end, block->status,
- block->requests, keycache->blocks_available));
- KEYCACHE_DBUG_ASSERT((ulong) keycache->blocks_available <=
- keycache->blocks_used);
-#endif
-}
-
-
-/*
- Unlink a block from the LRU chain
-
- SYNOPSIS
- unlink_block()
- keycache pointer to a key cache data structure
- block pointer to the block to unlink from the LRU chain
-
- RETURN VALUE
- none
-
- NOTES.
- See NOTES for link_block
-*/
-
-static void unlink_block(KEY_CACHE *keycache, BLOCK_LINK *block)
-{
- DBUG_ASSERT((block->status & ~BLOCK_CHANGED) == (BLOCK_READ | BLOCK_IN_USE));
- DBUG_ASSERT(block->hash_link); /*backptr to block NULL from free_block()*/
- DBUG_ASSERT(!block->requests);
- DBUG_ASSERT(block->prev_changed && *block->prev_changed == block);
- DBUG_ASSERT(block->next_used && block->prev_used &&
- (block->next_used->prev_used == &block->next_used) &&
- (*block->prev_used == block));
- if (block->next_used == block)
- /* The list contains only one member */
- keycache->used_last= keycache->used_ins= NULL;
- else
- {
- block->next_used->prev_used= block->prev_used;
- *block->prev_used= block->next_used;
- if (keycache->used_last == block)
- keycache->used_last= STRUCT_PTR(BLOCK_LINK, next_used, block->prev_used);
- if (keycache->used_ins == block)
- keycache->used_ins=STRUCT_PTR(BLOCK_LINK, next_used, block->prev_used);
- }
- block->next_used= NULL;
-#if !defined(DBUG_OFF)
- /*
- This makes it easier to see it's not in a chain during debugging.
- And some DBUG_ASSERT() rely on it.
- */
- block->prev_used= NULL;
-#endif
-
- KEYCACHE_THREAD_TRACE("unlink_block");
-#if defined(KEYCACHE_DEBUG)
- KEYCACHE_DBUG_ASSERT(keycache->blocks_available != 0);
- keycache->blocks_available--;
- KEYCACHE_DBUG_PRINT("unlink_block",
- ("unlinked block %u status=%x #requests=%u #available=%u",
- BLOCK_NUMBER(block), block->status,
- block->requests, keycache->blocks_available));
-#endif
-}
-
-
-/*
- Register requests for a block.
-
- SYNOPSIS
- reg_requests()
- keycache Pointer to a key cache data structure.
- block Pointer to the block to register a request on.
- count Number of requests. Always 1.
-
- NOTE
- The first request unlinks the block from the LRU ring. This means
- that it is protected against eveiction.
-
- RETURN
- void
-*/
-static void reg_requests(KEY_CACHE *keycache, BLOCK_LINK *block, int count)
-{
- DBUG_ASSERT(block->status & BLOCK_IN_USE);
- DBUG_ASSERT(block->hash_link);
-
- if (!block->requests)
- unlink_block(keycache, block);
- block->requests+=count;
-}
-
-
-/*
- Unregister request for a block
- linking it to the LRU chain if it's the last request
-
- SYNOPSIS
- unreg_request()
- keycache pointer to a key cache data structure
- block pointer to the block to link to the LRU chain
- at_end <-> to link the block at the end of the LRU chain
-
- RETURN VALUE
- none
-
- NOTES.
- Every linking to the LRU ring decrements by one a special block
- counter (if it's positive). If the at_end parameter is TRUE the block is
- added either at the end of warm sub-chain or at the end of hot sub-chain.
- It is added to the hot subchain if its counter is zero and number of
- blocks in warm sub-chain is not less than some low limit (determined by
- the division_limit parameter). Otherwise the block is added to the warm
- sub-chain. If the at_end parameter is FALSE the block is always added
- at beginning of the warm sub-chain.
- Thus a warm block can be promoted to the hot sub-chain when its counter
- becomes zero for the first time.
- At the same time the block at the very beginning of the hot subchain
- might be moved to the beginning of the warm subchain if it stays untouched
- for a too long time (this time is determined by parameter age_threshold).
-
- It is also possible that the block is selected for eviction and thus
- not linked in the LRU ring.
-*/
-
-static void unreg_request(KEY_CACHE *keycache,
- BLOCK_LINK *block, int at_end)
-{
- DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE));
- DBUG_ASSERT(block->hash_link); /*backptr to block NULL from free_block()*/
- DBUG_ASSERT(block->requests);
- DBUG_ASSERT(block->prev_changed && *block->prev_changed == block);
- DBUG_ASSERT(!block->next_used);
- DBUG_ASSERT(!block->prev_used);
- /*
- Unregister the request, but do not link erroneous blocks into the
- LRU ring.
- */
- if (!--block->requests && !(block->status & BLOCK_ERROR))
- {
- my_bool hot;
- if (block->hits_left)
- block->hits_left--;
- hot= !block->hits_left && at_end &&
- keycache->warm_blocks > keycache->min_warm_blocks;
- if (hot)
- {
- if (block->temperature == BLOCK_WARM)
- keycache->warm_blocks--;
- block->temperature= BLOCK_HOT;
- KEYCACHE_DBUG_PRINT("unreg_request", ("#warm_blocks: %lu",
- keycache->warm_blocks));
- }
- link_block(keycache, block, hot, (my_bool)at_end);
- block->last_hit_time= keycache->keycache_time;
- keycache->keycache_time++;
- /*
- At this place, the block might be in the LRU ring or not. If an
- evicter was waiting for a block, it was selected for eviction and
- not linked in the LRU ring.
- */
-
- /*
- Check if we should link a hot block to the warm block sub-chain.
- It is possible that we select the same block as above. But it can
- also be another block. In any case a block from the LRU ring is
- selected. In other words it works even if the above block was
- selected for eviction and not linked in the LRU ring. Since this
- happens only if the LRU ring is empty, the block selected below
- would be NULL and the rest of the function skipped.
- */
- block= keycache->used_ins;
- if (block && keycache->keycache_time - block->last_hit_time >
- keycache->age_threshold)
- {
- unlink_block(keycache, block);
- link_block(keycache, block, 0, 0);
- if (block->temperature != BLOCK_WARM)
- {
- keycache->warm_blocks++;
- block->temperature= BLOCK_WARM;
- }
- KEYCACHE_DBUG_PRINT("unreg_request", ("#warm_blocks: %lu",
- keycache->warm_blocks));
- }
- }
-}
-
-/*
- Remove a reader of the page in block
-*/
-
-static void remove_reader(BLOCK_LINK *block)
-{
- DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE));
- DBUG_ASSERT(block->hash_link && block->hash_link->block == block);
- DBUG_ASSERT(block->prev_changed && *block->prev_changed == block);
- DBUG_ASSERT(!block->next_used);
- DBUG_ASSERT(!block->prev_used);
- DBUG_ASSERT(block->hash_link->requests);
-
- if (! --block->hash_link->requests && block->condvar)
- keycache_pthread_cond_signal(block->condvar);
-}
-
-
-/*
- Wait until the last reader of the page in block
- signals on its termination
-*/
-
-static void wait_for_readers(KEY_CACHE *keycache,
- BLOCK_LINK *block)
-{
- struct st_my_thread_var *thread= my_thread_var;
- DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE));
- DBUG_ASSERT(!(block->status & (BLOCK_IN_FLUSH | BLOCK_CHANGED)));
- DBUG_ASSERT(block->hash_link);
- DBUG_ASSERT(block->hash_link->block == block);
- /* Linked in file_blocks or changed_blocks hash. */
- DBUG_ASSERT(block->prev_changed && *block->prev_changed == block);
- /* Not linked in LRU ring. */
- DBUG_ASSERT(!block->next_used);
- DBUG_ASSERT(!block->prev_used);
- while (block->hash_link->requests)
- {
- KEYCACHE_DBUG_PRINT("wait_for_readers: wait",
- ("suspend thread %ld block %u",
- thread->id, BLOCK_NUMBER(block)));
- /* There must be no other waiter. We have no queue here. */
- DBUG_ASSERT(!block->condvar);
- block->condvar= &thread->suspend;
- keycache_pthread_cond_wait(&thread->suspend, &keycache->cache_lock);
- block->condvar= NULL;
- }
-}
-
-
-/*
- Add a hash link to a bucket in the hash_table
-*/
-
-static inline void link_hash(HASH_LINK **start, HASH_LINK *hash_link)
-{
- if (*start)
- (*start)->prev= &hash_link->next;
- hash_link->next= *start;
- hash_link->prev= start;
- *start= hash_link;
-}
-
-
-/*
- Remove a hash link from the hash table
-*/
-
-static void unlink_hash(KEY_CACHE *keycache, HASH_LINK *hash_link)
-{
- KEYCACHE_DBUG_PRINT("unlink_hash", ("fd: %u pos_ %lu #requests=%u",
- (uint) hash_link->file,(ulong) hash_link->diskpos, hash_link->requests));
- KEYCACHE_DBUG_ASSERT(hash_link->requests == 0);
- if ((*hash_link->prev= hash_link->next))
- hash_link->next->prev= hash_link->prev;
- hash_link->block= NULL;
-
- if (keycache->waiting_for_hash_link.last_thread)
- {
- /* Signal that a free hash link has appeared */
- struct st_my_thread_var *last_thread=
- keycache->waiting_for_hash_link.last_thread;
- struct st_my_thread_var *first_thread= last_thread->next;
- struct st_my_thread_var *next_thread= first_thread;
- KEYCACHE_PAGE *first_page= (KEYCACHE_PAGE *) (first_thread->opt_info);
- struct st_my_thread_var *thread;
-
- hash_link->file= first_page->file;
- hash_link->diskpos= first_page->filepos;
- do
- {
- KEYCACHE_PAGE *page;
- thread= next_thread;
- page= (KEYCACHE_PAGE *) thread->opt_info;
- next_thread= thread->next;
- /*
- We notify about the event all threads that ask
- for the same page as the first thread in the queue
- */
- if (page->file == hash_link->file && page->filepos == hash_link->diskpos)
- {
- KEYCACHE_DBUG_PRINT("unlink_hash: signal", ("thread %ld", thread->id));
- keycache_pthread_cond_signal(&thread->suspend);
- unlink_from_queue(&keycache->waiting_for_hash_link, thread);
- }
- }
- while (thread != last_thread);
- link_hash(&keycache->hash_root[KEYCACHE_HASH(hash_link->file,
- hash_link->diskpos)],
- hash_link);
- return;
- }
- hash_link->next= keycache->free_hash_list;
- keycache->free_hash_list= hash_link;
-}
-
-
-/*
- Get the hash link for a page
-*/
-
-static HASH_LINK *get_hash_link(KEY_CACHE *keycache,
- int file, my_off_t filepos)
-{
- reg1 HASH_LINK *hash_link, **start;
-#if defined(KEYCACHE_DEBUG)
- int cnt;
-#endif
-
- KEYCACHE_DBUG_PRINT("get_hash_link", ("fd: %u pos: %lu",
- (uint) file,(ulong) filepos));
-
-restart:
- /*
- Find the bucket in the hash table for the pair (file, filepos);
- start contains the head of the bucket list,
- hash_link points to the first member of the list
- */
- hash_link= *(start= &keycache->hash_root[KEYCACHE_HASH(file, filepos)]);
-#if defined(KEYCACHE_DEBUG)
- cnt= 0;
-#endif
- /* Look for an element for the pair (file, filepos) in the bucket chain */
- while (hash_link &&
- (hash_link->diskpos != filepos || hash_link->file != file))
- {
- hash_link= hash_link->next;
-#if defined(KEYCACHE_DEBUG)
- cnt++;
- if (! (cnt <= keycache->hash_links_used))
- {
- int i;
- for (i=0, hash_link= *start ;
- i < cnt ; i++, hash_link= hash_link->next)
- {
- KEYCACHE_DBUG_PRINT("get_hash_link", ("fd: %u pos: %lu",
- (uint) hash_link->file,(ulong) hash_link->diskpos));
- }
- }
- KEYCACHE_DBUG_ASSERT(cnt <= keycache->hash_links_used);
-#endif
- }
- if (! hash_link)
- {
- /* There is no hash link in the hash table for the pair (file, filepos) */
- if (keycache->free_hash_list)
- {
- hash_link= keycache->free_hash_list;
- keycache->free_hash_list= hash_link->next;
- }
- else if (keycache->hash_links_used < keycache->hash_links)
- {
- hash_link= &keycache->hash_link_root[keycache->hash_links_used++];
- }
- else
- {
- /* 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;
- thread->opt_info= (void *) &page;
- link_into_queue(&keycache->waiting_for_hash_link, thread);
- KEYCACHE_DBUG_PRINT("get_hash_link: wait",
- ("suspend thread %ld", thread->id));
- keycache_pthread_cond_wait(&thread->suspend,
- &keycache->cache_lock);
- thread->opt_info= NULL;
- goto restart;
- }
- hash_link->file= file;
- hash_link->diskpos= filepos;
- link_hash(start, hash_link);
- }
- /* Register the request for the page */
- hash_link->requests++;
-
- return hash_link;
-}
-
-
-/*
- Get a block for the file page requested by a keycache read/write operation;
- If the page is not in the cache return a free block, if there is none
- return the lru block after saving its buffer if the page is dirty.
-
- SYNOPSIS
-
- find_key_block()
- keycache pointer to a key cache data structure
- file handler for the file to read page from
- filepos position of the page in the file
- init_hits_left how initialize the block counter for the page
- wrmode <-> get for writing
- page_st out {PAGE_READ,PAGE_TO_BE_READ,PAGE_WAIT_TO_BE_READ}
-
- RETURN VALUE
- Pointer to the found block if successful, 0 - otherwise
-
- NOTES.
- For the page from file positioned at filepos the function checks whether
- the page is in the key cache specified by the first parameter.
- If this is the case it immediately returns the block.
- If not, the function first chooses a block for this page. If there is
- no not used blocks in the key cache yet, the function takes the block
- at the very beginning of the warm sub-chain. It saves the page in that
- block if it's dirty before returning the pointer to it.
- The function returns in the page_st parameter the following values:
- PAGE_READ - if page already in the block,
- PAGE_TO_BE_READ - if it is to be read yet by the current thread
- WAIT_TO_BE_READ - if it is to be read by another thread
- If an error occurs THE BLOCK_ERROR bit is set in the block status.
- It might happen that there are no blocks in LRU chain (in warm part) -
- all blocks are unlinked for some read/write operations. Then the function
- waits until first of this operations links any block back.
-*/
-
-static BLOCK_LINK *find_key_block(KEY_CACHE *keycache,
- File file, my_off_t filepos,
- int init_hits_left,
- int wrmode, int *page_st)
-{
- HASH_LINK *hash_link;
- BLOCK_LINK *block;
- int error= 0;
- int page_status;
-
- DBUG_ENTER("find_key_block");
- KEYCACHE_THREAD_TRACE("find_key_block:begin");
- DBUG_PRINT("enter", ("fd: %d pos: %lu wrmode: %d",
- file, (ulong) filepos, wrmode));
- KEYCACHE_DBUG_PRINT("find_key_block", ("fd: %d pos: %lu wrmode: %d",
- file, (ulong) filepos,
- wrmode));
-#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
- DBUG_EXECUTE("check_keycache2",
- test_key_cache(keycache, "start of find_key_block", 0););
-#endif
-
-restart:
- /*
- If the flush phase of a resize operation fails, the cache is left
- unusable. This will be detected only after "goto restart".
- */
- if (!keycache->can_be_used)
- DBUG_RETURN(0);
-
- /*
- Find the hash_link for the requested file block (file, filepos). We
- do always get a hash_link here. It has registered our request so
- that no other thread can use it for another file block until we
- release the request (which is done by remove_reader() usually). The
- hash_link can have a block assigned to it or not. If there is a
- block, it may be assigned to this hash_link or not. In cases where a
- block is evicted from the cache, it is taken from the LRU ring and
- referenced by the new hash_link. But the block can still be assigned
- to its old hash_link for some time if it needs to be flushed first,
- or if there are other threads still reading it.
-
- Summary:
- hash_link is always returned.
- hash_link->block can be:
- - NULL or
- - not assigned to this hash_link or
- - assigned to this hash_link. If assigned, the block can have
- - invalid data (when freshly assigned) or
- - valid data. Valid data can be
- - changed over the file contents (dirty) or
- - not changed (clean).
- */
- hash_link= get_hash_link(keycache, file, filepos);
- DBUG_ASSERT((hash_link->file == file) && (hash_link->diskpos == filepos));
-
- page_status= -1;
- if ((block= hash_link->block) &&
- block->hash_link == hash_link && (block->status & BLOCK_READ))
- {
- /* Assigned block with valid (changed or unchanged) contents. */
- page_status= PAGE_READ;
- }
- /*
- else (page_status == -1)
- - block == NULL or
- - block not assigned to this hash_link or
- - block assigned but not yet read from file (invalid data).
- */
-
- if (keycache->in_resize)
- {
- /* This is a request during a resize operation */
-
- if (!block)
- {
- struct st_my_thread_var *thread;
-
- /*
- The file block is not in the cache. We don't need it in the
- cache: we are going to read or write directly to file. Cancel
- the request. We can simply decrement hash_link->requests because
- we did not release cache_lock since increasing it. So no other
- thread can wait for our request to become released.
- */
- if (hash_link->requests == 1)
- {
- /*
- We are the only one to request this hash_link (this file/pos).
- Free the hash_link.
- */
- hash_link->requests--;
- unlink_hash(keycache, hash_link);
- DBUG_RETURN(0);
- }
-
- /*
- More requests on the hash_link. Someone tries to evict a block
- for this hash_link (could have started before resizing started).
- This means that the LRU ring is empty. Otherwise a block could
- be assigned immediately. Behave like a thread that wants to
- evict a block for this file/pos. Add to the queue of threads
- waiting for a block. Wait until there is one assigned.
-
- Refresh the request on the hash-link so that it cannot be reused
- for another file/pos.
- */
- thread= my_thread_var;
- thread->opt_info= (void *) hash_link;
- link_into_queue(&keycache->waiting_for_block, thread);
- do
- {
- KEYCACHE_DBUG_PRINT("find_key_block: wait",
- ("suspend thread %ld", thread->id));
- keycache_pthread_cond_wait(&thread->suspend,
- &keycache->cache_lock);
- } while (thread->next);
- thread->opt_info= NULL;
- /*
- A block should now be assigned to the hash_link. But it may
- still need to be evicted. Anyway, we should re-check the
- situation. page_status must be set correctly.
- */
- hash_link->requests--;
- goto restart;
- } /* end of if (!block) */
-
- /*
- There is a block for this file/pos in the cache. Register a
- request on it. This unlinks it from the LRU ring (if it is there)
- and hence protects it against eviction (if not already in
- eviction). We need this for returning the block to the caller, for
- calling remove_reader() (for debugging purposes), and for calling
- free_block(). The only case where we don't need the request is if
- the block is in eviction. In that case we have to unregister the
- request later.
- */
- reg_requests(keycache, block, 1);
-
- if (page_status != PAGE_READ)
- {
- /*
- - block not assigned to this hash_link or
- - block assigned but not yet read from file (invalid data).
-
- This must be a block in eviction. It will be read soon. We need
- to wait here until this happened. Otherwise the caller could
- access a wrong block or a block which is in read. While waiting
- we cannot lose hash_link nor block. We have registered a request
- on the hash_link. Everything can happen to the block but changes
- in the hash_link -> block relationship. In other words:
- everything can happen to the block but free or another completed
- eviction.
-
- Note that we bahave like a secondary requestor here. We just
- cannot return with PAGE_WAIT_TO_BE_READ. This would work for
- read requests and writes on dirty blocks that are not in flush
- only. Waiting here on COND_FOR_REQUESTED works in all
- situations.
- */
- DBUG_ASSERT(((block->hash_link != hash_link) &&
- (block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH))) ||
- ((block->hash_link == hash_link) &&
- !(block->status & BLOCK_READ)));
- wait_on_queue(&block->wqueue[COND_FOR_REQUESTED], &keycache->cache_lock);
- /*
- Here we can trust that the block has been assigned to this
- hash_link (block->hash_link == hash_link) and read into the
- buffer (BLOCK_READ). The worst things possible here are that the
- block is in free (BLOCK_REASSIGNED). But the block is still
- assigned to the hash_link. The freeing thread waits until we
- release our request on the hash_link. The block must not be
- again in eviction because we registered an request on it before
- starting to wait.
- */
- DBUG_ASSERT(block->hash_link == hash_link);
- DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE));
- DBUG_ASSERT(!(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH)));
- }
- /*
- The block is in the cache. Assigned to the hash_link. Valid data.
- Note that in case of page_st == PAGE_READ, the block can be marked
- for eviction. In any case it can be marked for freeing.
- */
-
- if (!wrmode)
- {
- /* A reader can just read the block. */
- *page_st= PAGE_READ;
- DBUG_ASSERT((hash_link->file == file) &&
- (hash_link->diskpos == filepos) &&
- (block->hash_link == hash_link));
- DBUG_RETURN(block);
- }
-
- /*
- This is a writer. No two writers for the same block can exist.
- This must be assured by locks outside of the key cache.
- */
- DBUG_ASSERT(!(block->status & BLOCK_FOR_UPDATE) || fail_block(block));
-
- while (block->status & BLOCK_IN_FLUSH)
- {
- /*
- Wait until the block is flushed to file. Do not release the
- request on the hash_link yet to prevent that the block is freed
- or reassigned while we wait. While we wait, several things can
- happen to the block, including another flush. But the block
- cannot be reassigned to another hash_link until we release our
- request on it. But it can be marked BLOCK_REASSIGNED from free
- or eviction, while they wait for us to release the hash_link.
- */
- wait_on_queue(&block->wqueue[COND_FOR_SAVED], &keycache->cache_lock);
- /*
- If the flush phase failed, the resize could have finished while
- we waited here.
- */
- if (!keycache->in_resize)
- {
- remove_reader(block);
- unreg_request(keycache, block, 1);
- goto restart;
- }
- DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE));
- DBUG_ASSERT(!(block->status & BLOCK_FOR_UPDATE) || fail_block(block));
- DBUG_ASSERT(block->hash_link == hash_link);
- }
-
- if (block->status & BLOCK_CHANGED)
- {
- /*
- We want to write a block with changed contents. If the cache
- block size is bigger than the callers block size (e.g. MyISAM),
- the caller may replace part of the block only. Changes of the
- other part of the block must be preserved. Since the block has
- not yet been selected for flush, we can still add our changes.
- */
- *page_st= PAGE_READ;
- DBUG_ASSERT((hash_link->file == file) &&
- (hash_link->diskpos == filepos) &&
- (block->hash_link == hash_link));
- DBUG_RETURN(block);
- }
-
- /*
- This is a write request for a clean block. We do not want to have
- new dirty blocks in the cache while resizing. We will free the
- block and write directly to file. If the block is in eviction or
- in free, we just let it go.
-
- Unregister from the hash_link. This must be done before freeing
- the block. And it must be done if not freeing the block. Because
- we could have waited above, we need to call remove_reader(). Other
- threads could wait for us to release our request on the hash_link.
- */
- remove_reader(block);
-
- /* If the block is not in eviction and not in free, we can free it. */
- if (!(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH |
- BLOCK_REASSIGNED)))
- {
- /*
- Free block as we are going to write directly to file.
- Although we have an exlusive lock for the updated key part,
- the control can be yielded by the current thread as we might
- have unfinished readers of other key parts in the block
- buffer. Still we are guaranteed not to have any readers
- of the key part we are writing into until the block is
- removed from the cache as we set the BLOCK_REASSIGNED
- flag (see the code below that handles reading requests).
- */
- free_block(keycache, block);
- }
- else
- {
- /*
- The block will be evicted/freed soon. Don't touch it in any way.
- Unregister the request that we registered above.
- */
- unreg_request(keycache, block, 1);
-
- /*
- The block is still assigned to the hash_link (the file/pos that
- we are going to write to). Wait until the eviction/free is
- complete. Otherwise the direct write could complete before all
- readers are done with the block. So they could read outdated
- data.
-
- Since we released our request on the hash_link, it can be reused
- for another file/pos. Hence we cannot just check for
- block->hash_link == hash_link. As long as the resize is
- proceeding the block cannot be reassigned to the same file/pos
- again. So we can terminate the loop when the block is no longer
- assigned to this file/pos.
- */
- do
- {
- wait_on_queue(&block->wqueue[COND_FOR_SAVED],
- &keycache->cache_lock);
- /*
- If the flush phase failed, the resize could have finished
- while we waited here.
- */
- if (!keycache->in_resize)
- goto restart;
- } while (block->hash_link &&
- (block->hash_link->file == file) &&
- (block->hash_link->diskpos == filepos));
- }
- DBUG_RETURN(0);
- }
-
- if (page_status == PAGE_READ &&
- (block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH |
- BLOCK_REASSIGNED)))
- {
- /*
- This is a request for a block to be removed from cache. The block
- is assigned to this hash_link and contains valid data, but is
- marked for eviction or to be freed. Possible reasons why it has
- not yet been evicted/freed can be a flush before reassignment
- (BLOCK_IN_SWITCH), readers of the block have not finished yet
- (BLOCK_REASSIGNED), or the evicting thread did not yet awake after
- the block has been selected for it (BLOCK_IN_EVICTION).
- */
-
- KEYCACHE_DBUG_PRINT("find_key_block",
- ("request for old page in block %u "
- "wrmode: %d block->status: %d",
- BLOCK_NUMBER(block), wrmode, block->status));
- /*
- Only reading requests can proceed until the old dirty page is flushed,
- all others are to be suspended, then resubmitted
- */
- if (!wrmode && !(block->status & BLOCK_REASSIGNED))
- {
- /*
- This is a read request and the block not yet reassigned. We can
- register our request and proceed. This unlinks the block from
- the LRU ring and protects it against eviction.
- */
- reg_requests(keycache, block, 1);
- }
- else
- {
- /*
- Either this is a write request for a block that is in eviction
- or in free. We must not use it any more. Instead we must evict
- another block. But we cannot do this before the eviction/free is
- done. Otherwise we would find the same hash_link + block again
- and again.
-
- Or this is a read request for a block in eviction/free that does
- not require a flush, but waits for readers to finish with the
- block. We do not read this block to let the eviction/free happen
- as soon as possible. Again we must wait so that we don't find
- the same hash_link + block again and again.
- */
- DBUG_ASSERT(hash_link->requests);
- hash_link->requests--;
- KEYCACHE_DBUG_PRINT("find_key_block",
- ("request waiting for old page to be saved"));
- wait_on_queue(&block->wqueue[COND_FOR_SAVED], &keycache->cache_lock);
- KEYCACHE_DBUG_PRINT("find_key_block",
- ("request for old page resubmitted"));
- /*
- The block is no longer assigned to this hash_link.
- Get another one.
- */
- goto restart;
- }
- }
- else
- {
- /*
- This is a request for a new block or for a block not to be removed.
- Either
- - block == NULL or
- - block not assigned to this hash_link or
- - block assigned but not yet read from file,
- or
- - block assigned with valid (changed or unchanged) data and
- - it will not be reassigned/freed.
- */
- if (! block)
- {
- /* No block is assigned to the hash_link yet. */
- if (keycache->blocks_unused)
- {
- if (keycache->free_block_list)
- {
- /* There is a block in the free list. */
- block= keycache->free_block_list;
- keycache->free_block_list= block->next_used;
- block->next_used= NULL;
- }
- else
- {
- size_t block_mem_offset;
- /* There are some never used blocks, take first of them */
- DBUG_ASSERT(keycache->blocks_used <
- (ulong) keycache->disk_blocks);
- block= &keycache->block_root[keycache->blocks_used];
- block_mem_offset=
- ((size_t) keycache->blocks_used) * keycache->key_cache_block_size;
- block->buffer= ADD_TO_PTR(keycache->block_mem,
- block_mem_offset,
- uchar*);
- keycache->blocks_used++;
- DBUG_ASSERT(!block->next_used);
- }
- DBUG_ASSERT(!block->prev_used);
- DBUG_ASSERT(!block->next_changed);
- DBUG_ASSERT(!block->prev_changed);
- DBUG_ASSERT(!block->hash_link);
- DBUG_ASSERT(!block->status);
- DBUG_ASSERT(!block->requests);
- keycache->blocks_unused--;
- block->status= BLOCK_IN_USE;
- block->length= 0;
- block->offset= keycache->key_cache_block_size;
- block->requests= 1;
- block->temperature= BLOCK_COLD;
- block->hits_left= init_hits_left;
- block->last_hit_time= 0;
- block->hash_link= hash_link;
- hash_link->block= block;
- link_to_file_list(keycache, block, file, 0);
- page_status= PAGE_TO_BE_READ;
- KEYCACHE_DBUG_PRINT("find_key_block",
- ("got free or never used block %u",
- BLOCK_NUMBER(block)));
- }
- else
- {
- /*
- There are no free blocks and no never used blocks, use a block
- from the LRU ring.
- */
-
- if (! keycache->used_last)
- {
- /*
- The LRU ring is empty. Wait until a new block is added to
- it. Several threads might wait here for the same hash_link,
- all of them must get the same block. While waiting for a
- block, after a block is selected for this hash_link, other
- threads can run first before this one awakes. During this
- time interval other threads find this hash_link pointing to
- the block, which is still assigned to another hash_link. In
- this case the block is not marked BLOCK_IN_SWITCH yet, but
- it is marked BLOCK_IN_EVICTION.
- */
-
- struct st_my_thread_var *thread= my_thread_var;
- thread->opt_info= (void *) hash_link;
- link_into_queue(&keycache->waiting_for_block, thread);
- do
- {
- KEYCACHE_DBUG_PRINT("find_key_block: wait",
- ("suspend thread %ld", thread->id));
- keycache_pthread_cond_wait(&thread->suspend,
- &keycache->cache_lock);
- }
- while (thread->next);
- thread->opt_info= NULL;
- /* Assert that block has a request registered. */
- DBUG_ASSERT(hash_link->block->requests);
- /* Assert that block is not in LRU ring. */
- DBUG_ASSERT(!hash_link->block->next_used);
- DBUG_ASSERT(!hash_link->block->prev_used);
- }
-
- /*
- If we waited above, hash_link->block has been assigned by
- link_block(). Otherwise it is still NULL. In the latter case
- we need to grab a block from the LRU ring ourselves.
- */
- block= hash_link->block;
- if (! block)
- {
- /* Select the last block from the LRU ring. */
- block= keycache->used_last->next_used;
- block->hits_left= init_hits_left;
- block->last_hit_time= 0;
- hash_link->block= block;
- /*
- Register a request on the block. This unlinks it from the
- LRU ring and protects it against eviction.
- */
- DBUG_ASSERT(!block->requests);
- reg_requests(keycache, block,1);
- /*
- We do not need to set block->status|= BLOCK_IN_EVICTION here
- because we will set block->status|= BLOCK_IN_SWITCH
- immediately without releasing the lock in between. This does
- also support debugging. When looking at the block, one can
- see if the block has been selected by link_block() after the
- LRU ring was empty, or if it was grabbed directly from the
- LRU ring in this branch.
- */
- }
-
- /*
- If we had to wait above, there is a small chance that another
- thread grabbed this block for the same file block already. But
- in most cases the first condition is true.
- */
- if (block->hash_link != hash_link &&
- ! (block->status & BLOCK_IN_SWITCH) )
- {
- /* this is a primary request for a new page */
- block->status|= BLOCK_IN_SWITCH;
-
- KEYCACHE_DBUG_PRINT("find_key_block",
- ("got block %u for new page", BLOCK_NUMBER(block)));
-
- if (block->status & BLOCK_CHANGED)
- {
- /* The block contains a dirty page - push it out of the cache */
-
- KEYCACHE_DBUG_PRINT("find_key_block", ("block is dirty"));
- if (block->status & BLOCK_IN_FLUSH)
- {
- /*
- The block is marked for flush. If we do not wait here,
- it could happen that we write the block, reassign it to
- another file block, then, before the new owner can read
- the new file block, the flusher writes the cache block
- (which still has the old contents) to the new file block!
- */
- wait_on_queue(&block->wqueue[COND_FOR_SAVED],
- &keycache->cache_lock);
- /*
- The block is marked BLOCK_IN_SWITCH. It should be left
- alone except for reading. No free, no write.
- */
- DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE));
- DBUG_ASSERT(!(block->status & (BLOCK_REASSIGNED |
- BLOCK_CHANGED |
- BLOCK_FOR_UPDATE)));
- }
- else
- {
- block->status|= BLOCK_IN_FLUSH | BLOCK_IN_FLUSHWRITE;
- /*
- BLOCK_IN_EVICTION may be true or not. Other flags must
- have a fixed value.
- */
- DBUG_ASSERT((block->status & ~BLOCK_IN_EVICTION) ==
- (BLOCK_READ | BLOCK_IN_SWITCH |
- BLOCK_IN_FLUSH | BLOCK_IN_FLUSHWRITE |
- BLOCK_CHANGED | BLOCK_IN_USE));
- DBUG_ASSERT(block->hash_link);
-
- keycache_pthread_mutex_unlock(&keycache->cache_lock);
- /*
- The call is thread safe because only the current
- thread might change the block->hash_link value
- */
- error= my_pwrite(block->hash_link->file,
- block->buffer + block->offset,
- block->length - block->offset,
- block->hash_link->diskpos + block->offset,
- MYF(MY_NABP | MY_WAIT_IF_FULL));
- keycache_pthread_mutex_lock(&keycache->cache_lock);
-
- /* Block status must not have changed. */
- DBUG_ASSERT((block->status & ~BLOCK_IN_EVICTION) ==
- (BLOCK_READ | BLOCK_IN_SWITCH |
- BLOCK_IN_FLUSH | BLOCK_IN_FLUSHWRITE |
- BLOCK_CHANGED | BLOCK_IN_USE) || fail_block(block));
- keycache->global_cache_write++;
- }
- }
-
- block->status|= BLOCK_REASSIGNED;
- /*
- The block comes from the LRU ring. It must have a hash_link
- assigned.
- */
- DBUG_ASSERT(block->hash_link);
- if (block->hash_link)
- {
- /*
- All pending requests for this page must be resubmitted.
- This must be done before waiting for readers. They could
- wait for the flush to complete. And we must also do it
- after the wait. Flushers might try to free the block while
- we wait. They would wait until the reassignment is
- complete. Also the block status must reflect the correct
- situation: The block is not changed nor in flush any more.
- Note that we must not change the BLOCK_CHANGED flag
- outside of link_to_file_list() so that it is always in the
- correct queue and the *blocks_changed counters are
- correct.
- */
- block->status&= ~(BLOCK_IN_FLUSH | BLOCK_IN_FLUSHWRITE);
- link_to_file_list(keycache, block, block->hash_link->file, 1);
- release_whole_queue(&block->wqueue[COND_FOR_SAVED]);
- /*
- The block is still assigned to its old hash_link.
- Wait until all pending read requests
- for this page are executed
- (we could have avoided this waiting, if we had read
- a page in the cache in a sweep, without yielding control)
- */
- wait_for_readers(keycache, block);
- DBUG_ASSERT(block->hash_link && block->hash_link->block == block &&
- block->prev_changed);
- /* The reader must not have been a writer. */
- DBUG_ASSERT(!(block->status & BLOCK_CHANGED));
-
- /* Wake flushers that might have found the block in between. */
- release_whole_queue(&block->wqueue[COND_FOR_SAVED]);
-
- /* Remove the hash link for the old file block from the hash. */
- unlink_hash(keycache, block->hash_link);
-
- /*
- For sanity checks link_to_file_list() asserts that block
- and hash_link refer to each other. Hence we need to assign
- the hash_link first, but then we would not know if it was
- linked before. Hence we would not know if to unlink it. So
- unlink it here and call link_to_file_list(..., FALSE).
- */
- unlink_changed(block);
- }
- block->status= error ? BLOCK_ERROR : BLOCK_IN_USE ;
- block->length= 0;
- block->offset= keycache->key_cache_block_size;
- block->hash_link= hash_link;
- link_to_file_list(keycache, block, file, 0);
- page_status= PAGE_TO_BE_READ;
-
- KEYCACHE_DBUG_ASSERT(block->hash_link->block == block);
- KEYCACHE_DBUG_ASSERT(hash_link->block->hash_link == hash_link);
- }
- else
- {
- /*
- Either (block->hash_link == hash_link),
- or (block->status & BLOCK_IN_SWITCH).
-
- This is for secondary requests for a new file block only.
- Either it is already assigned to the new hash_link meanwhile
- (if we had to wait due to empty LRU), or it is already in
- eviction by another thread. Since this block has been
- grabbed from the LRU ring and attached to this hash_link,
- another thread cannot grab the same block from the LRU ring
- anymore. If the block is in eviction already, it must become
- attached to the same hash_link and as such destined for the
- same file block.
- */
- KEYCACHE_DBUG_PRINT("find_key_block",
- ("block->hash_link: %p hash_link: %p "
- "block->status: %u", block->hash_link,
- hash_link, block->status ));
- page_status= (((block->hash_link == hash_link) &&
- (block->status & BLOCK_READ)) ?
- PAGE_READ : PAGE_WAIT_TO_BE_READ);
- }
- }
- }
- else
- {
- /*
- Block is not NULL. This hash_link points to a block.
- Either
- - block not assigned to this hash_link (yet) or
- - block assigned but not yet read from file,
- or
- - block assigned with valid (changed or unchanged) data and
- - it will not be reassigned/freed.
-
- The first condition means hash_link points to a block in
- eviction. This is not necessarily marked by BLOCK_IN_SWITCH yet.
- But then it is marked BLOCK_IN_EVICTION. See the NOTE in
- link_block(). In both cases it is destined for this hash_link
- and its file block address. When this hash_link got its block
- address, the block was removed from the LRU ring and cannot be
- selected for eviction (for another hash_link) again.
-
- Register a request on the block. This is another protection
- against eviction.
- */
- DBUG_ASSERT(((block->hash_link != hash_link) &&
- (block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH))) ||
- ((block->hash_link == hash_link) &&
- !(block->status & BLOCK_READ)) ||
- ((block->status & BLOCK_READ) &&
- !(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH))));
- reg_requests(keycache, block, 1);
- KEYCACHE_DBUG_PRINT("find_key_block",
- ("block->hash_link: %p hash_link: %p "
- "block->status: %u", block->hash_link,
- hash_link, block->status ));
- page_status= (((block->hash_link == hash_link) &&
- (block->status & BLOCK_READ)) ?
- PAGE_READ : PAGE_WAIT_TO_BE_READ);
- }
- }
-
- KEYCACHE_DBUG_ASSERT(page_status != -1);
- /* Same assert basically, but be very sure. */
- KEYCACHE_DBUG_ASSERT(block);
- /* Assert that block has a request and is not in LRU ring. */
- DBUG_ASSERT(block->requests);
- DBUG_ASSERT(!block->next_used);
- DBUG_ASSERT(!block->prev_used);
- /* Assert that we return the correct block. */
- DBUG_ASSERT((page_status == PAGE_WAIT_TO_BE_READ) ||
- ((block->hash_link->file == file) &&
- (block->hash_link->diskpos == filepos)));
- *page_st=page_status;
- KEYCACHE_DBUG_PRINT("find_key_block",
- ("fd: %d pos: %lu block->status: %u page_status: %d",
- file, (ulong) filepos, block->status,
- page_status));
-
-#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
- DBUG_EXECUTE("check_keycache2",
- test_key_cache(keycache, "end of find_key_block",0););
-#endif
- KEYCACHE_THREAD_TRACE("find_key_block:end");
- DBUG_RETURN(block);
-}
-
-
-/*
- Read into a key cache block buffer from disk.
-
- SYNOPSIS
-
- read_block()
- keycache pointer to a key cache data structure
- block block to which buffer the data is to be read
- read_length size of data to be read
- min_length at least so much data must be read
- primary <-> the current thread will read the data
-
- RETURN VALUE
- None
-
- NOTES.
- The function either reads a page data from file to the block buffer,
- or waits until another thread reads it. What page to read is determined
- by a block parameter - reference to a hash link for this page.
- If an error occurs THE BLOCK_ERROR bit is set in the block status.
- We do not report error when the size of successfully read
- portion is less than read_length, but not less than min_length.
-*/
-
-static void read_block(KEY_CACHE *keycache,
- BLOCK_LINK *block, uint read_length,
- uint min_length, my_bool primary)
-{
- size_t got_length;
-
- /* On entry cache_lock is locked */
-
- KEYCACHE_THREAD_TRACE("read_block");
- if (primary)
- {
- /*
- This code is executed only by threads that submitted primary
- requests. Until block->status contains BLOCK_READ, all other
- request for the block become secondary requests. For a primary
- request the block must be properly initialized.
- */
- DBUG_ASSERT(((block->status & ~BLOCK_FOR_UPDATE) == BLOCK_IN_USE) ||
- fail_block(block));
- DBUG_ASSERT((block->length == 0) || fail_block(block));
- DBUG_ASSERT((block->offset == keycache->key_cache_block_size) ||
- fail_block(block));
- DBUG_ASSERT((block->requests > 0) || fail_block(block));
-
- KEYCACHE_DBUG_PRINT("read_block",
- ("page to be read by primary request"));
-
- keycache->global_cache_read++;
- /* Page is not in buffer yet, is to be read from disk */
- keycache_pthread_mutex_unlock(&keycache->cache_lock);
- /*
- Here other threads may step in and register as secondary readers.
- They will register in block->wqueue[COND_FOR_REQUESTED].
- */
- got_length= my_pread(block->hash_link->file, block->buffer,
- read_length, block->hash_link->diskpos, MYF(0));
- keycache_pthread_mutex_lock(&keycache->cache_lock);
- /*
- The block can now have been marked for free (in case of
- FLUSH_RELEASE). Otherwise the state must be unchanged.
- */
- DBUG_ASSERT(((block->status & ~(BLOCK_REASSIGNED |
- BLOCK_FOR_UPDATE)) == BLOCK_IN_USE) ||
- fail_block(block));
- DBUG_ASSERT((block->length == 0) || fail_block(block));
- DBUG_ASSERT((block->offset == keycache->key_cache_block_size) ||
- fail_block(block));
- DBUG_ASSERT((block->requests > 0) || fail_block(block));
-
- if (got_length < min_length)
- block->status|= BLOCK_ERROR;
- else
- {
- block->status|= BLOCK_READ;
- block->length= got_length;
- /*
- Do not set block->offset here. If this block is marked
- BLOCK_CHANGED later, we want to flush only the modified part. So
- only a writer may set block->offset down from
- keycache->key_cache_block_size.
- */
- }
- KEYCACHE_DBUG_PRINT("read_block",
- ("primary request: new page in cache"));
- /* Signal that all pending requests for this page now can be processed */
- release_whole_queue(&block->wqueue[COND_FOR_REQUESTED]);
- }
- else
- {
- /*
- This code is executed only by threads that submitted secondary
- requests. At this point it could happen that the cache block is
- not yet assigned to the hash_link for the requested file block.
- But at awake from the wait this should be the case. Unfortunately
- we cannot assert this here because we do not know the hash_link
- for the requested file block nor the file and position. So we have
- to assert this in the caller.
- */
- KEYCACHE_DBUG_PRINT("read_block",
- ("secondary request waiting for new page to be read"));
- wait_on_queue(&block->wqueue[COND_FOR_REQUESTED], &keycache->cache_lock);
- KEYCACHE_DBUG_PRINT("read_block",
- ("secondary request: new page in cache"));
- }
-}
-
-
-/*
- Read a block of data from a cached file into a buffer;
-
- SYNOPSIS
-
- key_cache_read()
- keycache pointer to a key cache data structure
- file handler for the file for the block of data to be read
- filepos position of the block of data in the file
- level determines the weight of the data
- buff buffer to where the data must be placed
- length length of the buffer
- block_length length of the block in the key cache buffer
- return_buffer return pointer to the key cache buffer with the data
-
- RETURN VALUE
- Returns address from where the data is placed if sucessful, 0 - otherwise.
-
- NOTES.
- The function ensures that a block of data of size length from file
- positioned at filepos is in the buffers for some key cache blocks.
- Then the function either copies the data into the buffer buff, or,
- if return_buffer is TRUE, it just returns the pointer to the key cache
- buffer with the data.
- Filepos must be a multiple of 'block_length', but it doesn't
- have to be a multiple of key_cache_block_size;
-*/
-
-uchar *key_cache_read(KEY_CACHE *keycache,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length,
- uint block_length __attribute__((unused)),
- int return_buffer __attribute__((unused)))
-{
- my_bool locked_and_incremented= FALSE;
- int error=0;
- uchar *start= buff;
- DBUG_ENTER("key_cache_read");
- DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u",
- (uint) file, (ulong) filepos, length));
-
- if (keycache->key_cache_inited)
- {
- /* Key cache is used */
- reg1 BLOCK_LINK *block;
- uint read_length;
- uint offset;
- int page_st;
-
- if (MYSQL_KEYCACHE_READ_START_ENABLED())
- {
- MYSQL_KEYCACHE_READ_START(my_filename(file), length,
- (ulong) (keycache->blocks_used *
- keycache->key_cache_block_size),
- (ulong) (keycache->blocks_unused *
- keycache->key_cache_block_size));
- }
-
- /*
- When the key cache is once initialized, we use the cache_lock to
- reliably distinguish the cases of normal operation, resizing, and
- disabled cache. We always increment and decrement
- 'cnt_for_resize_op' so that a resizer can wait for pending I/O.
- */
- keycache_pthread_mutex_lock(&keycache->cache_lock);
- /*
- Cache resizing has two phases: Flushing and re-initializing. In
- the flush phase read requests are allowed to bypass the cache for
- blocks not in the cache. find_key_block() returns NULL in this
- case.
-
- After the flush phase new I/O requests must wait until the
- re-initialization is done. The re-initialization can be done only
- if no I/O request is in progress. The reason is that
- key_cache_block_size can change. With enabled cache, I/O is done
- in chunks of key_cache_block_size. Every chunk tries to use a
- cache block first. If the block size changes in the middle, a
- block could be missed and old data could be read.
- */
- while (keycache->in_resize && !keycache->resize_in_flush)
- wait_on_queue(&keycache->resize_queue, &keycache->cache_lock);
- /* Register the I/O for the next resize. */
- inc_counter_for_resize_op(keycache);
- locked_and_incremented= TRUE;
- /* Requested data may not always be aligned to cache blocks. */
- offset= (uint) (filepos % keycache->key_cache_block_size);
- /* Read data in key_cache_block_size increments */
- do
- {
- /* Cache could be disabled in a later iteration. */
- if (!keycache->can_be_used)
- {
- KEYCACHE_DBUG_PRINT("key_cache_read", ("keycache cannot be used"));
- goto no_key_cache;
- }
- /* Start reading at the beginning of the cache block. */
- filepos-= offset;
- /* Do not read beyond the end of the cache block. */
- read_length= length;
- set_if_smaller(read_length, keycache->key_cache_block_size-offset);
- KEYCACHE_DBUG_ASSERT(read_length > 0);
-
- if (block_length > keycache->key_cache_block_size || offset)
- return_buffer=0;
-
- /* Request the cache block that matches file/pos. */
- keycache->global_cache_r_requests++;
-
- MYSQL_KEYCACHE_READ_BLOCK(keycache->key_cache_block_size);
-
- block=find_key_block(keycache, file, filepos, level, 0, &page_st);
- if (!block)
- {
- /*
- This happens only for requests submitted during key cache
- resize. The block is not in the cache and shall not go in.
- Read directly from file.
- */
- keycache->global_cache_read++;
- keycache_pthread_mutex_unlock(&keycache->cache_lock);
- error= (my_pread(file, (uchar*) buff, read_length,
- filepos + offset, MYF(MY_NABP)) != 0);
- keycache_pthread_mutex_lock(&keycache->cache_lock);
- goto next_block;
- }
- if (!(block->status & BLOCK_ERROR))
- {
- if (page_st != PAGE_READ)
- {
- MYSQL_KEYCACHE_READ_MISS();
- /* The requested page is to be read into the block buffer */
- read_block(keycache, block,
- keycache->key_cache_block_size, read_length+offset,
- (my_bool)(page_st == PAGE_TO_BE_READ));
- /*
- A secondary request must now have the block assigned to the
- requested file block. It does not hurt to check it for
- primary requests too.
- */
- DBUG_ASSERT(keycache->can_be_used);
- DBUG_ASSERT(block->hash_link->file == file);
- DBUG_ASSERT(block->hash_link->diskpos == filepos);
- DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE));
- }
- else if (block->length < read_length + offset)
- {
- /*
- Impossible if nothing goes wrong:
- this could only happen if we are using a file with
- small key blocks and are trying to read outside the file
- */
- my_errno= -1;
- block->status|= BLOCK_ERROR;
- }
- else
- {
- MYSQL_KEYCACHE_READ_HIT();
- }
- }
-
- /* block status may have added BLOCK_ERROR in the above 'if'. */
- if (!(block->status & BLOCK_ERROR))
- {
- {
- DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE));
-#if !defined(SERIALIZED_READ_FROM_CACHE)
- keycache_pthread_mutex_unlock(&keycache->cache_lock);
-#endif
-
- /* Copy data from the cache buffer */
- memcpy(buff, block->buffer+offset, (size_t) read_length);
-
-#if !defined(SERIALIZED_READ_FROM_CACHE)
- keycache_pthread_mutex_lock(&keycache->cache_lock);
- DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE));
-#endif
- }
- }
-
- remove_reader(block);
-
- /* Error injection for coverage testing. */
- DBUG_EXECUTE_IF("key_cache_read_block_error",
- block->status|= BLOCK_ERROR;);
-
- /* Do not link erroneous blocks into the LRU ring, but free them. */
- if (!(block->status & BLOCK_ERROR))
- {
- /*
- Link the block into the LRU ring if it's the last submitted
- request for the block. This enables eviction for the block.
- */
- unreg_request(keycache, block, 1);
- }
- else
- {
- free_block(keycache, block);
- error= 1;
- break;
- }
-
- next_block:
- buff+= read_length;
- filepos+= read_length+offset;
- offset= 0;
-
- } while ((length-= read_length));
- if (MYSQL_KEYCACHE_READ_DONE_ENABLED())
- {
- MYSQL_KEYCACHE_READ_DONE((ulong) (keycache->blocks_used *
- keycache->key_cache_block_size),
- (ulong) (keycache->blocks_unused *
- keycache->key_cache_block_size));
- }
- goto end;
- }
- KEYCACHE_DBUG_PRINT("key_cache_read", ("keycache not initialized"));
-
-no_key_cache:
- /* Key cache is not used */
-
- keycache->global_cache_r_requests++;
- keycache->global_cache_read++;
-
- if (locked_and_incremented)
- keycache_pthread_mutex_unlock(&keycache->cache_lock);
- if (my_pread(file, (uchar*) buff, length, filepos, MYF(MY_NABP)))
- error= 1;
- if (locked_and_incremented)
- keycache_pthread_mutex_lock(&keycache->cache_lock);
-
-end:
- if (locked_and_incremented)
- {
- dec_counter_for_resize_op(keycache);
- keycache_pthread_mutex_unlock(&keycache->cache_lock);
- }
- DBUG_PRINT("exit", ("error: %d", error ));
- DBUG_RETURN(error ? (uchar*) 0 : start);
-}
-
-
-/*
- Insert a block of file data from a buffer into key cache
-
- SYNOPSIS
- key_cache_insert()
- keycache pointer to a key cache data structure
- file handler for the file to insert data from
- filepos position of the block of data in the file to insert
- level determines the weight of the data
- buff buffer to read data from
- length length of the data in the buffer
-
- NOTES
- This is used by MyISAM to move all blocks from a index file to the key
- cache
-
- RETURN VALUE
- 0 if a success, 1 - otherwise.
-*/
-
-int key_cache_insert(KEY_CACHE *keycache,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length)
-{
- int error= 0;
- DBUG_ENTER("key_cache_insert");
- DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u",
- (uint) file,(ulong) filepos, length));
-
- if (keycache->key_cache_inited)
- {
- /* Key cache is used */
- reg1 BLOCK_LINK *block;
- uint read_length;
- uint offset;
- int page_st;
- my_bool locked_and_incremented= FALSE;
-
- /*
- When the keycache is once initialized, we use the cache_lock to
- reliably distinguish the cases of normal operation, resizing, and
- disabled cache. We always increment and decrement
- 'cnt_for_resize_op' so that a resizer can wait for pending I/O.
- */
- keycache_pthread_mutex_lock(&keycache->cache_lock);
- /*
- We do not load index data into a disabled cache nor into an
- ongoing resize.
- */
- if (!keycache->can_be_used || keycache->in_resize)
- goto no_key_cache;
- /* Register the pseudo I/O for the next resize. */
- inc_counter_for_resize_op(keycache);
- locked_and_incremented= TRUE;
- /* Loaded data may not always be aligned to cache blocks. */
- offset= (uint) (filepos % keycache->key_cache_block_size);
- /* Load data in key_cache_block_size increments. */
- do
- {
- /* Cache could be disabled or resizing in a later iteration. */
- if (!keycache->can_be_used || keycache->in_resize)
- goto no_key_cache;
- /* Start loading at the beginning of the cache block. */
- filepos-= offset;
- /* Do not load beyond the end of the cache block. */
- read_length= length;
- set_if_smaller(read_length, keycache->key_cache_block_size-offset);
- KEYCACHE_DBUG_ASSERT(read_length > 0);
-
- /* The block has been read by the caller already. */
- keycache->global_cache_read++;
- /* Request the cache block that matches file/pos. */
- keycache->global_cache_r_requests++;
- block= find_key_block(keycache, file, filepos, level, 0, &page_st);
- if (!block)
- {
- /*
- This happens only for requests submitted during key cache
- resize. The block is not in the cache and shall not go in.
- Stop loading index data.
- */
- goto no_key_cache;
- }
- if (!(block->status & BLOCK_ERROR))
- {
- if ((page_st == PAGE_WAIT_TO_BE_READ) ||
- ((page_st == PAGE_TO_BE_READ) &&
- (offset || (read_length < keycache->key_cache_block_size))))
- {
- /*
- Either
-
- this is a secondary request for a block to be read into the
- cache. The block is in eviction. It is not yet assigned to
- the requested file block (It does not point to the right
- hash_link). So we cannot call remove_reader() on the block.
- And we cannot access the hash_link directly here. We need to
- wait until the assignment is complete. read_block() executes
- the correct wait when called with primary == FALSE.
-
- Or
-
- this is a primary request for a block to be read into the
- cache and the supplied data does not fill the whole block.
-
- This function is called on behalf of a LOAD INDEX INTO CACHE
- statement, which is a read-only task and allows other
- readers. It is possible that a parallel running reader tries
- to access this block. If it needs more data than has been
- supplied here, it would report an error. To be sure that we
- have all data in the block that is available in the file, we
- read the block ourselves.
-
- Though reading again what the caller did read already is an
- expensive operation, we need to do this for correctness.
- */
- read_block(keycache, block, keycache->key_cache_block_size,
- read_length + offset, (page_st == PAGE_TO_BE_READ));
- /*
- A secondary request must now have the block assigned to the
- requested file block. It does not hurt to check it for
- primary requests too.
- */
- DBUG_ASSERT(keycache->can_be_used);
- DBUG_ASSERT(block->hash_link->file == file);
- DBUG_ASSERT(block->hash_link->diskpos == filepos);
- DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE));
- }
- else if (page_st == PAGE_TO_BE_READ)
- {
- /*
- This is a new block in the cache. If we come here, we have
- data for the whole block.
- */
- DBUG_ASSERT(block->hash_link->requests);
- DBUG_ASSERT(block->status & BLOCK_IN_USE);
- DBUG_ASSERT((page_st == PAGE_TO_BE_READ) ||
- (block->status & BLOCK_READ));
-
-#if !defined(SERIALIZED_READ_FROM_CACHE)
- keycache_pthread_mutex_unlock(&keycache->cache_lock);
- /*
- Here other threads may step in and register as secondary readers.
- They will register in block->wqueue[COND_FOR_REQUESTED].
- */
-#endif
-
- /* Copy data from buff */
- memcpy(block->buffer+offset, buff, (size_t) read_length);
-
-#if !defined(SERIALIZED_READ_FROM_CACHE)
- keycache_pthread_mutex_lock(&keycache->cache_lock);
- DBUG_ASSERT(block->status & BLOCK_IN_USE);
- DBUG_ASSERT((page_st == PAGE_TO_BE_READ) ||
- (block->status & BLOCK_READ));
-#endif
- /*
- After the data is in the buffer, we can declare the block
- valid. Now other threads do not need to register as
- secondary readers any more. They can immediately access the
- block.
- */
- block->status|= BLOCK_READ;
- block->length= read_length+offset;
- /*
- Do not set block->offset here. If this block is marked
- BLOCK_CHANGED later, we want to flush only the modified part. So
- only a writer may set block->offset down from
- keycache->key_cache_block_size.
- */
- KEYCACHE_DBUG_PRINT("key_cache_insert",
- ("primary request: new page in cache"));
- /* Signal all pending requests. */
- release_whole_queue(&block->wqueue[COND_FOR_REQUESTED]);
- }
- else
- {
- /*
- page_st == PAGE_READ. The block is in the buffer. All data
- must already be present. Blocks are always read with all
- data available on file. Assert that the block does not have
- less contents than the preloader supplies. If the caller has
- data beyond block->length, it means that a file write has
- been done while this block was in cache and not extended
- with the new data. If the condition is met, we can simply
- ignore the block.
- */
- DBUG_ASSERT((page_st == PAGE_READ) &&
- (read_length + offset <= block->length));
- }
-
- /*
- A secondary request must now have the block assigned to the
- requested file block. It does not hurt to check it for primary
- requests too.
- */
- DBUG_ASSERT(block->hash_link->file == file);
- DBUG_ASSERT(block->hash_link->diskpos == filepos);
- DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE));
- } /* end of if (!(block->status & BLOCK_ERROR)) */
-
- remove_reader(block);
-
- /* Error injection for coverage testing. */
- DBUG_EXECUTE_IF("key_cache_insert_block_error",
- block->status|= BLOCK_ERROR; errno=EIO;);
-
- /* Do not link erroneous blocks into the LRU ring, but free them. */
- if (!(block->status & BLOCK_ERROR))
- {
- /*
- Link the block into the LRU ring if it's the last submitted
- request for the block. This enables eviction for the block.
- */
- unreg_request(keycache, block, 1);
- }
- else
- {
- free_block(keycache, block);
- error= 1;
- break;
- }
-
- buff+= read_length;
- filepos+= read_length+offset;
- offset= 0;
-
- } while ((length-= read_length));
-
- no_key_cache:
- if (locked_and_incremented)
- dec_counter_for_resize_op(keycache);
- keycache_pthread_mutex_unlock(&keycache->cache_lock);
- }
- DBUG_RETURN(error);
-}
-
-
-/*
- Write a buffer into a cached file.
-
- SYNOPSIS
-
- key_cache_write()
- keycache pointer to a key cache data structure
- file handler for the file to write data to
- filepos position in the file to write data to
- level determines the weight of the data
- buff buffer with the data
- length length of the buffer
- dont_write if is 0 then all dirty pages involved in writing
- should have been flushed from key cache
-
- RETURN VALUE
- 0 if a success, 1 - otherwise.
-
- NOTES.
- The function copies the data of size length from buff into buffers
- for key cache blocks that are assigned to contain the portion of
- the file starting with position filepos.
- It ensures that this data is flushed to the file if dont_write is FALSE.
- Filepos must be a multiple of 'block_length', but it doesn't
- have to be a multiple of key_cache_block_size;
-
- dont_write is always TRUE in the server (info->lock_type is never F_UNLCK).
-*/
-
-int key_cache_write(KEY_CACHE *keycache,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length,
- uint block_length __attribute__((unused)),
- int dont_write)
-{
- my_bool locked_and_incremented= FALSE;
- int error=0;
- DBUG_ENTER("key_cache_write");
- DBUG_PRINT("enter",
- ("fd: %u pos: %lu length: %u block_length: %u"
- " key_block_length: %u",
- (uint) file, (ulong) filepos, length, block_length,
- keycache ? keycache->key_cache_block_size : 0));
-
- if (!dont_write)
- {
- /* purecov: begin inspected */
- /* Not used in the server. */
- /* Force writing from buff into disk. */
- keycache->global_cache_w_requests++;
- keycache->global_cache_write++;
- if (my_pwrite(file, buff, length, filepos, MYF(MY_NABP | MY_WAIT_IF_FULL)))
- DBUG_RETURN(1);
- /* purecov: end */
- }
-
-#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
- DBUG_EXECUTE("check_keycache",
- test_key_cache(keycache, "start of key_cache_write", 1););
-#endif
-
- if (keycache->key_cache_inited)
- {
- /* Key cache is used */
- reg1 BLOCK_LINK *block;
- uint read_length;
- uint offset;
- int page_st;
-
- if (MYSQL_KEYCACHE_WRITE_START_ENABLED())
- {
- MYSQL_KEYCACHE_WRITE_START(my_filename(file), length,
- (ulong) (keycache->blocks_used *
- keycache->key_cache_block_size),
- (ulong) (keycache->blocks_unused *
- keycache->key_cache_block_size));
- }
-
- /*
- When the key cache is once initialized, we use the cache_lock to
- reliably distinguish the cases of normal operation, resizing, and
- disabled cache. We always increment and decrement
- 'cnt_for_resize_op' so that a resizer can wait for pending I/O.
- */
- keycache_pthread_mutex_lock(&keycache->cache_lock);
- /*
- Cache resizing has two phases: Flushing and re-initializing. In
- the flush phase write requests can modify dirty blocks that are
- not yet in flush. Otherwise they are allowed to bypass the cache.
- find_key_block() returns NULL in both cases (clean blocks and
- non-cached blocks).
-
- After the flush phase new I/O requests must wait until the
- re-initialization is done. The re-initialization can be done only
- if no I/O request is in progress. The reason is that
- key_cache_block_size can change. With enabled cache I/O is done in
- chunks of key_cache_block_size. Every chunk tries to use a cache
- block first. If the block size changes in the middle, a block
- could be missed and data could be written below a cached block.
- */
- while (keycache->in_resize && !keycache->resize_in_flush)
- wait_on_queue(&keycache->resize_queue, &keycache->cache_lock);
- /* Register the I/O for the next resize. */
- inc_counter_for_resize_op(keycache);
- locked_and_incremented= TRUE;
- /* Requested data may not always be aligned to cache blocks. */
- offset= (uint) (filepos % keycache->key_cache_block_size);
- /* Write data in key_cache_block_size increments. */
- do
- {
- /* Cache could be disabled in a later iteration. */
- if (!keycache->can_be_used)
- goto no_key_cache;
-
- MYSQL_KEYCACHE_WRITE_BLOCK(keycache->key_cache_block_size);
- /* Start writing at the beginning of the cache block. */
- filepos-= offset;
- /* Do not write beyond the end of the cache block. */
- read_length= length;
- set_if_smaller(read_length, keycache->key_cache_block_size-offset);
- KEYCACHE_DBUG_ASSERT(read_length > 0);
-
- /* Request the cache block that matches file/pos. */
- keycache->global_cache_w_requests++;
- block= find_key_block(keycache, file, filepos, level, 1, &page_st);
- if (!block)
- {
- /*
- This happens only for requests submitted during key cache
- resize. The block is not in the cache and shall not go in.
- Write directly to file.
- */
- if (dont_write)
- {
- /* Used in the server. */
- keycache->global_cache_write++;
- keycache_pthread_mutex_unlock(&keycache->cache_lock);
- if (my_pwrite(file, (uchar*) buff, read_length, filepos + offset,
- MYF(MY_NABP | MY_WAIT_IF_FULL)))
- error=1;
- keycache_pthread_mutex_lock(&keycache->cache_lock);
- }
- goto next_block;
- }
- /*
- Prevent block from flushing and from being selected for to be
- freed. This must be set when we release the cache_lock.
- However, we must not set the status of the block before it is
- assigned to this file/pos.
- */
- if (page_st != PAGE_WAIT_TO_BE_READ)
- block->status|= BLOCK_FOR_UPDATE;
- /*
- We must read the file block first if it is not yet in the cache
- and we do not replace all of its contents.
-
- In cases where the cache block is big enough to contain (parts
- of) index blocks of different indexes, our request can be
- secondary (PAGE_WAIT_TO_BE_READ). In this case another thread is
- reading the file block. If the read completes after us, it
- overwrites our new contents with the old contents. So we have to
- wait for the other thread to complete the read of this block.
- read_block() takes care for the wait.
- */
- if (!(block->status & BLOCK_ERROR) &&
- ((page_st == PAGE_TO_BE_READ &&
- (offset || read_length < keycache->key_cache_block_size)) ||
- (page_st == PAGE_WAIT_TO_BE_READ)))
- {
- read_block(keycache, block,
- offset + read_length >= keycache->key_cache_block_size?
- offset : keycache->key_cache_block_size,
- offset, (page_st == PAGE_TO_BE_READ));
- DBUG_ASSERT(keycache->can_be_used);
- DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE));
- /*
- Prevent block from flushing and from being selected for to be
- freed. This must be set when we release the cache_lock.
- Here we set it in case we could not set it above.
- */
- block->status|= BLOCK_FOR_UPDATE;
- }
- /*
- The block should always be assigned to the requested file block
- here. It need not be BLOCK_READ when overwriting the whole block.
- */
- DBUG_ASSERT(block->hash_link->file == file);
- DBUG_ASSERT(block->hash_link->diskpos == filepos);
- DBUG_ASSERT(block->status & BLOCK_IN_USE);
- DBUG_ASSERT((page_st == PAGE_TO_BE_READ) || (block->status & BLOCK_READ));
- /*
- The block to be written must not be marked BLOCK_REASSIGNED.
- Otherwise it could be freed in dirty state or reused without
- another flush during eviction. It must also not be in flush.
- Otherwise the old contens may have been flushed already and
- the flusher could clear BLOCK_CHANGED without flushing the
- new changes again.
- */
- DBUG_ASSERT(!(block->status & BLOCK_REASSIGNED));
-
- while (block->status & BLOCK_IN_FLUSHWRITE)
- {
- /*
- Another thread is flushing the block. It was dirty already.
- Wait until the block is flushed to file. Otherwise we could
- modify the buffer contents just while it is written to file.
- An unpredictable file block contents would be the result.
- While we wait, several things can happen to the block,
- including another flush. But the block cannot be reassigned to
- another hash_link until we release our request on it.
- */
- wait_on_queue(&block->wqueue[COND_FOR_SAVED], &keycache->cache_lock);
- DBUG_ASSERT(keycache->can_be_used);
- DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE));
- /* Still must not be marked for free. */
- DBUG_ASSERT(!(block->status & BLOCK_REASSIGNED));
- DBUG_ASSERT(block->hash_link && (block->hash_link->block == block));
- }
-
- /*
- We could perhaps release the cache_lock during access of the
- data like in the other functions. Locks outside of the key cache
- assure that readers and a writer do not access the same range of
- data. Parallel accesses should happen only if the cache block
- contains multiple index block(fragment)s. So different parts of
- the buffer would be read/written. An attempt to flush during
- memcpy() is prevented with BLOCK_FOR_UPDATE.
- */
- if (!(block->status & BLOCK_ERROR))
- {
-#if !defined(SERIALIZED_READ_FROM_CACHE)
- keycache_pthread_mutex_unlock(&keycache->cache_lock);
-#endif
- memcpy(block->buffer+offset, buff, (size_t) read_length);
-
-#if !defined(SERIALIZED_READ_FROM_CACHE)
- keycache_pthread_mutex_lock(&keycache->cache_lock);
-#endif
- }
-
- if (!dont_write)
- {
- /* Not used in the server. buff has been written to disk at start. */
- if ((block->status & BLOCK_CHANGED) &&
- (!offset && read_length >= keycache->key_cache_block_size))
- link_to_file_list(keycache, block, block->hash_link->file, 1);
- }
- else if (! (block->status & BLOCK_CHANGED))
- link_to_changed_list(keycache, block);
- block->status|=BLOCK_READ;
- /*
- Allow block to be selected for to be freed. Since it is marked
- BLOCK_CHANGED too, it won't be selected for to be freed without
- a flush.
- */
- block->status&= ~BLOCK_FOR_UPDATE;
- set_if_smaller(block->offset, offset);
- set_if_bigger(block->length, read_length+offset);
-
- /* Threads may be waiting for the changes to be complete. */
- release_whole_queue(&block->wqueue[COND_FOR_REQUESTED]);
-
- /*
- If only a part of the cache block is to be replaced, and the
- rest has been read from file, then the cache lock has been
- released for I/O and it could be possible that another thread
- wants to evict or free the block and waits for it to be
- released. So we must not just decrement hash_link->requests, but
- also wake a waiting thread.
- */
- remove_reader(block);
-
- /* Error injection for coverage testing. */
- DBUG_EXECUTE_IF("key_cache_write_block_error",
- block->status|= BLOCK_ERROR;);
-
- /* Do not link erroneous blocks into the LRU ring, but free them. */
- if (!(block->status & BLOCK_ERROR))
- {
- /*
- Link the block into the LRU ring if it's the last submitted
- request for the block. This enables eviction for the block.
- */
- unreg_request(keycache, block, 1);
- }
- else
- {
- /* Pretend a "clean" block to avoid complications. */
- block->status&= ~(BLOCK_CHANGED);
- free_block(keycache, block);
- error= 1;
- break;
- }
-
- next_block:
- buff+= read_length;
- filepos+= read_length+offset;
- offset= 0;
-
- } while ((length-= read_length));
- goto end;
- }
-
-no_key_cache:
- /* Key cache is not used */
- if (dont_write)
- {
- /* Used in the server. */
- keycache->global_cache_w_requests++;
- keycache->global_cache_write++;
- if (locked_and_incremented)
- keycache_pthread_mutex_unlock(&keycache->cache_lock);
- if (my_pwrite(file, (uchar*) buff, length, filepos,
- MYF(MY_NABP | MY_WAIT_IF_FULL)))
- error=1;
- if (locked_and_incremented)
- keycache_pthread_mutex_lock(&keycache->cache_lock);
- }
-
-end:
- if (locked_and_incremented)
- {
- dec_counter_for_resize_op(keycache);
- keycache_pthread_mutex_unlock(&keycache->cache_lock);
- }
-
- if (MYSQL_KEYCACHE_WRITE_DONE_ENABLED())
- {
- MYSQL_KEYCACHE_WRITE_DONE((ulong) (keycache->blocks_used *
- keycache->key_cache_block_size),
- (ulong) (keycache->blocks_unused *
- keycache->key_cache_block_size));
- }
-
-#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
- DBUG_EXECUTE("exec",
- test_key_cache(keycache, "end of key_cache_write", 1););
-#endif
- DBUG_RETURN(error);
-}
-
-
-/*
- Free block.
-
- SYNOPSIS
- free_block()
- keycache Pointer to a key cache data structure
- block Pointer to the block to free
-
- DESCRIPTION
- Remove reference to block from hash table.
- Remove block from the chain of clean blocks.
- Add block to the free list.
-
- NOTE
- Block must not be free (status == 0).
- Block must not be in free_block_list.
- Block must not be in the LRU ring.
- Block must not be in eviction (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH).
- Block must not be in free (BLOCK_REASSIGNED).
- Block must not be in flush (BLOCK_IN_FLUSH).
- Block must not be dirty (BLOCK_CHANGED).
- Block must not be in changed_blocks (dirty) hash.
- Block must be in file_blocks (clean) hash.
- Block must refer to a hash_link.
- Block must have a request registered on it.
-*/
-
-static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block)
-{
- KEYCACHE_THREAD_TRACE("free block");
- KEYCACHE_DBUG_PRINT("free_block",
- ("block %u to be freed, hash_link %p status: %u",
- BLOCK_NUMBER(block), block->hash_link,
- block->status));
- /*
- Assert that the block is not free already. And that it is in a clean
- state. Note that the block might just be assigned to a hash_link and
- not yet read (BLOCK_READ may not be set here). In this case a reader
- is registered in the hash_link and free_block() will wait for it
- below.
- */
- DBUG_ASSERT((block->status & BLOCK_IN_USE) &&
- !(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH |
- BLOCK_REASSIGNED | BLOCK_IN_FLUSH |
- BLOCK_CHANGED | BLOCK_FOR_UPDATE)));
- /* Assert that the block is in a file_blocks chain. */
- DBUG_ASSERT(block->prev_changed && *block->prev_changed == block);
- /* Assert that the block is not in the LRU ring. */
- DBUG_ASSERT(!block->next_used && !block->prev_used);
- /*
- IMHO the below condition (if()) makes no sense. I can't see how it
- could be possible that free_block() is entered with a NULL hash_link
- pointer. The only place where it can become NULL is in free_block()
- (or before its first use ever, but for those blocks free_block() is
- not called). I don't remove the conditional as it cannot harm, but
- place an DBUG_ASSERT to confirm my hypothesis. Eventually the
- condition (if()) can be removed.
- */
- DBUG_ASSERT(block->hash_link && block->hash_link->block == block);
- if (block->hash_link)
- {
- /*
- While waiting for readers to finish, new readers might request the
- block. But since we set block->status|= BLOCK_REASSIGNED, they
- will wait on block->wqueue[COND_FOR_SAVED]. They must be signalled
- later.
- */
- block->status|= BLOCK_REASSIGNED;
- wait_for_readers(keycache, block);
- /*
- The block must not have been freed by another thread. Repeat some
- checks. An additional requirement is that it must be read now
- (BLOCK_READ).
- */
- DBUG_ASSERT(block->hash_link && block->hash_link->block == block);
- DBUG_ASSERT((block->status & (BLOCK_READ | BLOCK_IN_USE |
- BLOCK_REASSIGNED)) &&
- !(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH |
- BLOCK_IN_FLUSH | BLOCK_CHANGED |
- BLOCK_FOR_UPDATE)));
- DBUG_ASSERT(block->prev_changed && *block->prev_changed == block);
- DBUG_ASSERT(!block->prev_used);
- /*
- Unset BLOCK_REASSIGNED again. If we hand the block to an evicting
- thread (through unreg_request() below), other threads must not see
- this flag. They could become confused.
- */
- block->status&= ~BLOCK_REASSIGNED;
- /*
- Do not release the hash_link until the block is off all lists.
- At least not if we hand it over for eviction in unreg_request().
- */
- }
-
- /*
- Unregister the block request and link the block into the LRU ring.
- This enables eviction for the block. If the LRU ring was empty and
- threads are waiting for a block, then the block wil be handed over
- for eviction immediately. Otherwise we will unlink it from the LRU
- ring again, without releasing the lock in between. So decrementing
- the request counter and updating statistics are the only relevant
- operation in this case. Assert that there are no other requests
- registered.
- */
- DBUG_ASSERT(block->requests == 1);
- unreg_request(keycache, block, 0);
- /*
- Note that even without releasing the cache lock it is possible that
- the block is immediately selected for eviction by link_block() and
- thus not added to the LRU ring. In this case we must not touch the
- block any more.
- */
- if (block->status & BLOCK_IN_EVICTION)
- return;
-
- /* Error blocks are not put into the LRU ring. */
- if (!(block->status & BLOCK_ERROR))
- {
- /* Here the block must be in the LRU ring. Unlink it again. */
- DBUG_ASSERT(block->next_used && block->prev_used &&
- *block->prev_used == block);
- unlink_block(keycache, block);
- }
- if (block->temperature == BLOCK_WARM)
- keycache->warm_blocks--;
- block->temperature= BLOCK_COLD;
-
- /* Remove from file_blocks hash. */
- unlink_changed(block);
-
- /* Remove reference to block from hash table. */
- unlink_hash(keycache, block->hash_link);
- block->hash_link= NULL;
-
- block->status= 0;
- block->length= 0;
- block->offset= keycache->key_cache_block_size;
- KEYCACHE_THREAD_TRACE("free block");
- KEYCACHE_DBUG_PRINT("free_block", ("block is freed"));
-
- /* Enforced by unlink_changed(), but just to be sure. */
- DBUG_ASSERT(!block->next_changed && !block->prev_changed);
- /* Enforced by unlink_block(): not in LRU ring nor in free_block_list. */
- DBUG_ASSERT(!block->next_used && !block->prev_used);
- /* Insert the free block in the free list. */
- block->next_used= keycache->free_block_list;
- keycache->free_block_list= block;
- /* Keep track of the number of currently unused blocks. */
- keycache->blocks_unused++;
-
- /* All pending requests for this page must be resubmitted. */
- release_whole_queue(&block->wqueue[COND_FOR_SAVED]);
-}
-
-
-static int cmp_sec_link(BLOCK_LINK **a, BLOCK_LINK **b)
-{
- return (((*a)->hash_link->diskpos < (*b)->hash_link->diskpos) ? -1 :
- ((*a)->hash_link->diskpos > (*b)->hash_link->diskpos) ? 1 : 0);
-}
-
-
-/*
- Flush a portion of changed blocks to disk,
- free used blocks if requested
-*/
-
-static int flush_cached_blocks(KEY_CACHE *keycache,
- File file, BLOCK_LINK **cache,
- BLOCK_LINK **end,
- enum flush_type type)
-{
- int error;
- int last_errno= 0;
- uint count= (uint) (end-cache);
-
- /* Don't lock the cache during the flush */
- keycache_pthread_mutex_unlock(&keycache->cache_lock);
- /*
- As all blocks referred in 'cache' are marked by BLOCK_IN_FLUSH
- we are guarunteed no thread will change them
- */
- my_qsort((uchar*) cache, count, sizeof(*cache), (qsort_cmp) cmp_sec_link);
-
- keycache_pthread_mutex_lock(&keycache->cache_lock);
- /*
- Note: Do not break the loop. We have registered a request on every
- block in 'cache'. These must be unregistered by free_block() or
- unreg_request().
- */
- for ( ; cache != end ; cache++)
- {
- BLOCK_LINK *block= *cache;
-
- KEYCACHE_DBUG_PRINT("flush_cached_blocks",
- ("block %u to be flushed", BLOCK_NUMBER(block)));
- /*
- If the block contents is going to be changed, we abandon the flush
- for this block. flush_key_blocks_int() will restart its search and
- handle the block properly.
- */
- if (!(block->status & BLOCK_FOR_UPDATE))
- {
- /* Blocks coming here must have a certain status. */
- DBUG_ASSERT(block->hash_link);
- DBUG_ASSERT(block->hash_link->block == block);
- DBUG_ASSERT(block->hash_link->file == file);
- DBUG_ASSERT((block->status & ~BLOCK_IN_EVICTION) ==
- (BLOCK_READ | BLOCK_IN_FLUSH | BLOCK_CHANGED | BLOCK_IN_USE));
- block->status|= BLOCK_IN_FLUSHWRITE;
- keycache_pthread_mutex_unlock(&keycache->cache_lock);
- error= my_pwrite(file, block->buffer+block->offset,
- block->length - block->offset,
- block->hash_link->diskpos+ block->offset,
- MYF(MY_NABP | MY_WAIT_IF_FULL));
- keycache_pthread_mutex_lock(&keycache->cache_lock);
- keycache->global_cache_write++;
- if (error)
- {
- block->status|= BLOCK_ERROR;
- if (!last_errno)
- last_errno= errno ? errno : -1;
- }
- block->status&= ~BLOCK_IN_FLUSHWRITE;
- /* Block must not have changed status except BLOCK_FOR_UPDATE. */
- DBUG_ASSERT(block->hash_link);
- DBUG_ASSERT(block->hash_link->block == block);
- DBUG_ASSERT(block->hash_link->file == file);
- DBUG_ASSERT((block->status & ~(BLOCK_FOR_UPDATE | BLOCK_IN_EVICTION)) ==
- (BLOCK_READ | BLOCK_IN_FLUSH | BLOCK_CHANGED | BLOCK_IN_USE));
- /*
- Set correct status and link in right queue for free or later use.
- free_block() must not see BLOCK_CHANGED and it may need to wait
- for readers of the block. These should not see the block in the
- wrong hash. If not freeing the block, we need to have it in the
- right queue anyway.
- */
- link_to_file_list(keycache, block, file, 1);
- }
- block->status&= ~BLOCK_IN_FLUSH;
- /*
- 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.
- */
- release_whole_queue(&block->wqueue[COND_FOR_SAVED]);
- /* type will never be FLUSH_IGNORE_CHANGED here */
- if (!(type == FLUSH_KEEP || type == FLUSH_FORCE_WRITE) &&
- !(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH |
- BLOCK_FOR_UPDATE)))
- {
- /*
- Note that a request has been registered against the block in
- flush_key_blocks_int().
- */
- free_block(keycache, block);
- }
- else
- {
- /*
- Link the block into the LRU ring if it's the last submitted
- request for the block. This enables eviction for the block.
- Note that a request has been registered against the block in
- flush_key_blocks_int().
- */
- unreg_request(keycache, block, 1);
- }
-
- } /* end of for ( ; cache != end ; cache++) */
- return last_errno;
-}
-
-
-/*
- Flush all key blocks for a file to disk, but don't do any mutex locks.
-
- SYNOPSIS
- flush_key_blocks_int()
- keycache pointer to a key cache data structure
- file handler for the file to flush to
- flush_type type of the flush
-
- NOTES
- This function doesn't do any mutex locks because it needs to be called both
- from flush_key_blocks and flush_all_key_blocks (the later one does the
- mutex lock in the resize_key_cache() function).
-
- We do only care about changed blocks that exist when the function is
- entered. We do not guarantee that all changed blocks of the file are
- flushed if more blocks change while this function is running.
-
- RETURN
- 0 ok
- 1 error
-*/
-
-static int flush_key_blocks_int(KEY_CACHE *keycache,
- File file, enum flush_type type)
-{
- BLOCK_LINK *cache_buff[FLUSH_CACHE],**cache;
- int last_errno= 0;
- int last_errcnt= 0;
- DBUG_ENTER("flush_key_blocks_int");
- DBUG_PRINT("enter",("file: %d blocks_used: %lu blocks_changed: %lu",
- file, keycache->blocks_used, keycache->blocks_changed));
-
-#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
- DBUG_EXECUTE("check_keycache",
- test_key_cache(keycache, "start of flush_key_blocks", 0););
-#endif
-
- cache= cache_buff;
- if (keycache->disk_blocks > 0 &&
- (!my_disable_flush_key_blocks || type != FLUSH_KEEP))
- {
- /* Key cache exists and flush is not disabled */
- int error= 0;
- uint count= FLUSH_CACHE;
- BLOCK_LINK **pos,**end;
- BLOCK_LINK *first_in_switch= NULL;
- BLOCK_LINK *last_in_flush;
- BLOCK_LINK *last_for_update;
- BLOCK_LINK *block, *next;
-#if defined(KEYCACHE_DEBUG)
- uint cnt=0;
-#endif
-
- if (type != FLUSH_IGNORE_CHANGED)
- {
- /*
- Count how many key blocks we have to cache to be able
- to flush all dirty pages with minimum seek moves
- */
- count= 0;
- for (block= keycache->changed_blocks[FILE_HASH(file)] ;
- block ;
- block= block->next_changed)
- {
- if ((block->hash_link->file == file) &&
- !(block->status & BLOCK_IN_FLUSH))
- {
- count++;
- KEYCACHE_DBUG_ASSERT(count<= keycache->blocks_used);
- }
- }
- /*
- Allocate a new buffer only if its bigger than the one we have.
- Assure that we always have some entries for the case that new
- changed blocks appear while we need to wait for something.
- */
- if ((count > FLUSH_CACHE) &&
- !(cache= (BLOCK_LINK**) my_malloc(sizeof(BLOCK_LINK*)*count,
- MYF(0))))
- cache= cache_buff;
- /*
- After a restart there could be more changed blocks than now.
- So we should not let count become smaller than the fixed buffer.
- */
- if (cache == cache_buff)
- count= FLUSH_CACHE;
- }
-
- /* Retrieve the blocks and write them to a buffer to be flushed */
-restart:
- last_in_flush= NULL;
- last_for_update= NULL;
- end= (pos= cache)+count;
- for (block= keycache->changed_blocks[FILE_HASH(file)] ;
- block ;
- block= next)
- {
-#if defined(KEYCACHE_DEBUG)
- cnt++;
- KEYCACHE_DBUG_ASSERT(cnt <= keycache->blocks_used);
-#endif
- next= block->next_changed;
- if (block->hash_link->file == file)
- {
- if (!(block->status & (BLOCK_IN_FLUSH | BLOCK_FOR_UPDATE)))
- {
- /*
- Note: The special handling of BLOCK_IN_SWITCH is obsolete
- since we set BLOCK_IN_FLUSH if the eviction includes a
- flush. It can be removed in a later version.
- */
- if (!(block->status & BLOCK_IN_SWITCH))
- {
- /*
- We care only for the blocks for which flushing was not
- initiated by another thread and which are not in eviction.
- Registering a request on the block unlinks it from the LRU
- ring and protects against eviction.
- */
- reg_requests(keycache, block, 1);
- if (type != FLUSH_IGNORE_CHANGED)
- {
- /* It's not a temporary file */
- if (pos == end)
- {
- /*
- This should happen relatively seldom. Remove the
- request because we won't do anything with the block
- but restart and pick it again in the next iteration.
- */
- unreg_request(keycache, block, 0);
- /*
- This happens only if there is not enough
- memory for the big block
- */
- if ((error= flush_cached_blocks(keycache, file, cache,
- end,type)))
- {
- /* Do not loop infinitely trying to flush in vain. */
- if ((last_errno == error) && (++last_errcnt > 5))
- goto err;
- last_errno= error;
- }
- /*
- Restart the scan as some other thread might have changed
- the changed blocks chain: the blocks that were in switch
- state before the flush started have to be excluded
- */
- goto restart;
- }
- /*
- Mark the block with BLOCK_IN_FLUSH in order not to let
- other threads to use it for new pages and interfere with
- our sequence of flushing dirty file pages. We must not
- set this flag before actually putting the block on the
- write burst array called 'cache'.
- */
- block->status|= BLOCK_IN_FLUSH;
- /* Add block to the array for a write burst. */
- *pos++= block;
- }
- else
- {
- /* It's a temporary file */
- DBUG_ASSERT(!(block->status & BLOCK_REASSIGNED));
- /*
- free_block() must not be called with BLOCK_CHANGED. Note
- that we must not change the BLOCK_CHANGED flag outside of
- link_to_file_list() so that it is always in the correct
- queue and the *blocks_changed counters are correct.
- */
- link_to_file_list(keycache, block, file, 1);
- if (!(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH)))
- {
- /* A request has been registered against the block above. */
- free_block(keycache, block);
- }
- else
- {
- /*
- Link the block into the LRU ring if it's the last
- submitted request for the block. This enables eviction
- for the block. A request has been registered against
- the block above.
- */
- unreg_request(keycache, block, 1);
- }
- }
- }
- else
- {
- /*
- Link the block into a list of blocks 'in switch'.
-
- WARNING: Here we introduce a place where a changed block
- is not in the changed_blocks hash! This is acceptable for
- a BLOCK_IN_SWITCH. Never try this for another situation.
- Other parts of the key cache code rely on changed blocks
- being in the changed_blocks hash.
- */
- unlink_changed(block);
- link_changed(block, &first_in_switch);
- }
- }
- else if (type != FLUSH_KEEP)
- {
- /*
- During the normal flush at end of statement (FLUSH_KEEP) we
- do not need to ensure that blocks in flush or update by
- other threads are flushed. They will be flushed by them
- later. In all other cases we must assure that we do not have
- any changed block of this file in the cache when this
- function returns.
- */
- if (block->status & BLOCK_IN_FLUSH)
- {
- /* Remember the last block found to be in flush. */
- last_in_flush= block;
- }
- else
- {
- /* Remember the last block found to be selected for update. */
- last_for_update= block;
- }
- }
- }
- }
- if (pos != cache)
- {
- if ((error= flush_cached_blocks(keycache, file, cache, pos, type)))
- {
- /* Do not loop inifnitely trying to flush in vain. */
- if ((last_errno == error) && (++last_errcnt > 5))
- goto err;
- last_errno= error;
- }
- /*
- Do not restart here during the normal flush at end of statement
- (FLUSH_KEEP). We have now flushed at least all blocks that were
- changed when entering this function. In all other cases we must
- assure that we do not have any changed block of this file in the
- cache when this function returns.
- */
- if (type != FLUSH_KEEP)
- goto restart;
- }
- if (last_in_flush)
- {
- /*
- There are no blocks to be flushed by this thread, but blocks in
- flush by other threads. Wait until one of the blocks is flushed.
- Re-check the condition for last_in_flush. We may have unlocked
- the cache_lock in flush_cached_blocks(). The state of the block
- could have changed.
- */
- if (last_in_flush->status & BLOCK_IN_FLUSH)
- wait_on_queue(&last_in_flush->wqueue[COND_FOR_SAVED],
- &keycache->cache_lock);
- /* Be sure not to lose a block. They may be flushed in random order. */
- goto restart;
- }
- if (last_for_update)
- {
- /*
- There are no blocks to be flushed by this thread, but blocks for
- update by other threads. Wait until one of the blocks is updated.
- Re-check the condition for last_for_update. We may have unlocked
- the cache_lock in flush_cached_blocks(). The state of the block
- could have changed.
- */
- if (last_for_update->status & BLOCK_FOR_UPDATE)
- wait_on_queue(&last_for_update->wqueue[COND_FOR_REQUESTED],
- &keycache->cache_lock);
- /* The block is now changed. Flush it. */
- goto restart;
- }
-
- /*
- Wait until the list of blocks in switch is empty. The threads that
- are switching these blocks will relink them to clean file chains
- while we wait and thus empty the 'first_in_switch' chain.
- */
- while (first_in_switch)
- {
-#if defined(KEYCACHE_DEBUG)
- cnt= 0;
-#endif
- wait_on_queue(&first_in_switch->wqueue[COND_FOR_SAVED],
- &keycache->cache_lock);
-#if defined(KEYCACHE_DEBUG)
- cnt++;
- KEYCACHE_DBUG_ASSERT(cnt <= keycache->blocks_used);
-#endif
- /*
- Do not restart here. We have flushed all blocks that were
- changed when entering this function and were not marked for
- eviction. Other threads have now flushed all remaining blocks in
- the course of their eviction.
- */
- }
-
- if (! (type == FLUSH_KEEP || type == FLUSH_FORCE_WRITE))
- {
- BLOCK_LINK *last_for_update= NULL;
- BLOCK_LINK *last_in_switch= NULL;
- uint total_found= 0;
- uint found;
-
- /*
- Finally free all clean blocks for this file.
- During resize this may be run by two threads in parallel.
- */
- do
- {
- found= 0;
- for (block= keycache->file_blocks[FILE_HASH(file)] ;
- block ;
- block= next)
- {
- /* Remember the next block. After freeing we cannot get at it. */
- next= block->next_changed;
-
- /* Changed blocks cannot appear in the file_blocks hash. */
- DBUG_ASSERT(!(block->status & BLOCK_CHANGED));
- if (block->hash_link->file == file)
- {
- /* We must skip blocks that will be changed. */
- if (block->status & BLOCK_FOR_UPDATE)
- {
- last_for_update= block;
- continue;
- }
-
- /*
- We must not free blocks in eviction (BLOCK_IN_EVICTION |
- BLOCK_IN_SWITCH) or blocks intended to be freed
- (BLOCK_REASSIGNED).
- */
- if (!(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH |
- BLOCK_REASSIGNED)))
- {
- struct st_hash_link *UNINIT_VAR(next_hash_link);
- my_off_t UNINIT_VAR(next_diskpos);
- File UNINIT_VAR(next_file);
- uint UNINIT_VAR(next_status);
- uint UNINIT_VAR(hash_requests);
-
- total_found++;
- found++;
- KEYCACHE_DBUG_ASSERT(found <= keycache->blocks_used);
-
- /*
- Register a request. This unlinks the block from the LRU
- ring and protects it against eviction. This is required
- by free_block().
- */
- reg_requests(keycache, block, 1);
-
- /*
- free_block() may need to wait for readers of the block.
- This is the moment where the other thread can move the
- 'next' block from the chain. free_block() needs to wait
- if there are requests for the block pending.
- */
- if (next && (hash_requests= block->hash_link->requests))
- {
- /* Copy values from the 'next' block and its hash_link. */
- next_status= next->status;
- next_hash_link= next->hash_link;
- next_diskpos= next_hash_link->diskpos;
- next_file= next_hash_link->file;
- DBUG_ASSERT(next == next_hash_link->block);
- }
-
- free_block(keycache, block);
- /*
- If we had to wait and the state of the 'next' block
- changed, break the inner loop. 'next' may no longer be
- part of the current chain.
-
- We do not want to break the loop after every free_block(),
- not even only after waits. The chain might be quite long
- and contain blocks for many files. Traversing it again and
- again to find more blocks for this file could become quite
- inefficient.
- */
- if (next && hash_requests &&
- ((next_status != next->status) ||
- (next_hash_link != next->hash_link) ||
- (next_file != next_hash_link->file) ||
- (next_diskpos != next_hash_link->diskpos) ||
- (next != next_hash_link->block)))
- break;
- }
- else
- {
- last_in_switch= block;
- }
- }
- } /* end for block in file_blocks */
- } while (found);
-
- /*
- If any clean block has been found, we may have waited for it to
- become free. In this case it could be possible that another clean
- block became dirty. This is possible if the write request existed
- before the flush started (BLOCK_FOR_UPDATE). Re-check the hashes.
- */
- if (total_found)
- goto restart;
-
- /*
- To avoid an infinite loop, wait until one of the blocks marked
- for update is updated.
- */
- if (last_for_update)
- {
- /* We did not wait. Block must not have changed status. */
- DBUG_ASSERT(last_for_update->status & BLOCK_FOR_UPDATE);
- wait_on_queue(&last_for_update->wqueue[COND_FOR_REQUESTED],
- &keycache->cache_lock);
- goto restart;
- }
-
- /*
- To avoid an infinite loop wait until one of the blocks marked
- for eviction is switched.
- */
- if (last_in_switch)
- {
- /* We did not wait. Block must not have changed status. */
- DBUG_ASSERT(last_in_switch->status & (BLOCK_IN_EVICTION |
- BLOCK_IN_SWITCH |
- BLOCK_REASSIGNED));
- wait_on_queue(&last_in_switch->wqueue[COND_FOR_SAVED],
- &keycache->cache_lock);
- goto restart;
- }
-
- } /* if (! (type == FLUSH_KEEP || type == FLUSH_FORCE_WRITE)) */
-
- } /* if (keycache->disk_blocks > 0 */
-
-#ifndef DBUG_OFF
- DBUG_EXECUTE("check_keycache",
- test_key_cache(keycache, "end of flush_key_blocks", 0););
-#endif
-err:
- if (cache != cache_buff)
- my_free(cache);
- if (last_errno)
- errno=last_errno; /* Return first error */
- DBUG_RETURN(last_errno != 0);
-}
-
-
-/*
- Flush all blocks for a file to disk
-
- SYNOPSIS
-
- flush_key_blocks()
- keycache pointer to a key cache data structure
- file handler for the file to flush to
- flush_type type of the flush
-
- RETURN
- 0 ok
- 1 error
-*/
-
-int flush_key_blocks(KEY_CACHE *keycache,
- File file, enum flush_type type)
-{
- int res= 0;
- DBUG_ENTER("flush_key_blocks");
- DBUG_PRINT("enter", ("keycache: 0x%lx", (long) keycache));
-
- if (!keycache->key_cache_inited)
- DBUG_RETURN(0);
-
- keycache_pthread_mutex_lock(&keycache->cache_lock);
- /* While waiting for lock, keycache could have been ended. */
- if (keycache->disk_blocks > 0)
- {
- inc_counter_for_resize_op(keycache);
- res= flush_key_blocks_int(keycache, file, type);
- dec_counter_for_resize_op(keycache);
- }
- keycache_pthread_mutex_unlock(&keycache->cache_lock);
- DBUG_RETURN(res);
-}
-
-
-/*
- Flush all blocks in the key cache to disk.
-
- SYNOPSIS
- flush_all_key_blocks()
- keycache pointer to key cache root structure
-
- DESCRIPTION
-
- Flushing of the whole key cache is done in two phases.
-
- 1. Flush all changed blocks, waiting for them if necessary. Loop
- until there is no changed block left in the cache.
-
- 2. Free all clean blocks. Normally this means free all blocks. The
- changed blocks were flushed in phase 1 and became clean. However we
- may need to wait for blocks that are read by other threads. While we
- wait, a clean block could become changed if that operation started
- before the resize operation started. To be safe we must restart at
- phase 1.
-
- When we can run through the changed_blocks and file_blocks hashes
- without finding a block any more, then we are done.
-
- Note that we hold keycache->cache_lock all the time unless we need
- to wait for something.
-
- RETURN
- 0 OK
- != 0 Error
-*/
-
-static int flush_all_key_blocks(KEY_CACHE *keycache)
-{
- BLOCK_LINK *block;
- uint total_found;
- uint found;
- uint idx;
- DBUG_ENTER("flush_all_key_blocks");
-
- do
- {
- mysql_mutex_assert_owner(&keycache->cache_lock);
- total_found= 0;
-
- /*
- Phase1: Flush all changed blocks, waiting for them if necessary.
- Loop until there is no changed block left in the cache.
- */
- do
- {
- found= 0;
- /* Step over the whole changed_blocks hash array. */
- for (idx= 0; idx < CHANGED_BLOCKS_HASH; idx++)
- {
- /*
- If an array element is non-empty, use the first block from its
- chain to find a file for flush. All changed blocks for this
- file are flushed. So the same block will not appear at this
- place again with the next iteration. New writes for blocks are
- not accepted during the flush. If multiple files share the
- same hash bucket, one of them will be flushed per iteration
- of the outer loop of phase 1.
- */
- if ((block= keycache->changed_blocks[idx]))
- {
- found++;
- /*
- Flush dirty blocks but do not free them yet. They can be used
- for reading until all other blocks are flushed too.
- */
- if (flush_key_blocks_int(keycache, block->hash_link->file,
- FLUSH_FORCE_WRITE))
- DBUG_RETURN(1);
- }
- }
-
- } while (found);
-
- /*
- Phase 2: Free all clean blocks. Normally this means free all
- blocks. The changed blocks were flushed in phase 1 and became
- clean. However we may need to wait for blocks that are read by
- other threads. While we wait, a clean block could become changed
- if that operation started before the resize operation started. To
- be safe we must restart at phase 1.
- */
- do
- {
- found= 0;
- /* Step over the whole file_blocks hash array. */
- for (idx= 0; idx < CHANGED_BLOCKS_HASH; idx++)
- {
- /*
- If an array element is non-empty, use the first block from its
- chain to find a file for flush. All blocks for this file are
- freed. So the same block will not appear at this place again
- with the next iteration. If multiple files share the
- same hash bucket, one of them will be flushed per iteration
- of the outer loop of phase 2.
- */
- if ((block= keycache->file_blocks[idx]))
- {
- total_found++;
- found++;
- if (flush_key_blocks_int(keycache, block->hash_link->file,
- FLUSH_RELEASE))
- DBUG_RETURN(1);
- }
- }
-
- } while (found);
-
- /*
- If any clean block has been found, we may have waited for it to
- become free. In this case it could be possible that another clean
- block became dirty. This is possible if the write request existed
- before the resize started (BLOCK_FOR_UPDATE). Re-check the hashes.
- */
- } while (total_found);
-
-#ifndef DBUG_OFF
- /* Now there should not exist any block any more. */
- for (idx= 0; idx < CHANGED_BLOCKS_HASH; idx++)
- {
- DBUG_ASSERT(!keycache->changed_blocks[idx]);
- DBUG_ASSERT(!keycache->file_blocks[idx]);
- }
-#endif
-
- DBUG_RETURN(0);
-}
-
-
-/*
- Reset the counters of a key cache.
-
- SYNOPSIS
- reset_key_cache_counters()
- name the name of a key cache
- key_cache pointer to the key kache to be reset
-
- DESCRIPTION
- This procedure is used by process_key_caches() to reset the counters of all
- currently used key caches, both the default one and the named ones.
-
- RETURN
- 0 on success (always because it can't fail)
-*/
-
-int reset_key_cache_counters(const char *name __attribute__((unused)),
- KEY_CACHE *key_cache)
-{
- DBUG_ENTER("reset_key_cache_counters");
- if (!key_cache->key_cache_inited)
- {
- DBUG_PRINT("info", ("Key cache %s not initialized.", name));
- DBUG_RETURN(0);
- }
- DBUG_PRINT("info", ("Resetting counters for key cache %s.", name));
-
- key_cache->global_blocks_changed= 0; /* Key_blocks_not_flushed */
- key_cache->global_cache_r_requests= 0; /* Key_read_requests */
- key_cache->global_cache_read= 0; /* Key_reads */
- key_cache->global_cache_w_requests= 0; /* Key_write_requests */
- key_cache->global_cache_write= 0; /* Key_writes */
- DBUG_RETURN(0);
-}
-
-
-#ifndef DBUG_OFF
-/*
- Test if disk-cache is ok
-*/
-static void test_key_cache(KEY_CACHE *keycache __attribute__((unused)),
- const char *where __attribute__((unused)),
- my_bool lock __attribute__((unused)))
-{
- /* TODO */
-}
-#endif
-
-#if defined(KEYCACHE_TIMEOUT)
-
-#define KEYCACHE_DUMP_FILE "keycache_dump.txt"
-#define MAX_QUEUE_LEN 100
-
-
-static void keycache_dump(KEY_CACHE *keycache)
-{
- FILE *keycache_dump_file=fopen(KEYCACHE_DUMP_FILE, "w");
- struct st_my_thread_var *last;
- struct st_my_thread_var *thread;
- BLOCK_LINK *block;
- HASH_LINK *hash_link;
- KEYCACHE_PAGE *page;
- uint i;
-
- fprintf(keycache_dump_file, "thread:%u\n", thread->id);
-
- i=0;
- thread=last=waiting_for_hash_link.last_thread;
- fprintf(keycache_dump_file, "queue of threads waiting for hash link\n");
- if (thread)
- do
- {
- thread=thread->next;
- page= (KEYCACHE_PAGE *) thread->opt_info;
- fprintf(keycache_dump_file,
- "thread:%u, (file,filepos)=(%u,%lu)\n",
- thread->id,(uint) page->file,(ulong) page->filepos);
- if (++i == MAX_QUEUE_LEN)
- break;
- }
- while (thread != last);
-
- i=0;
- thread=last=waiting_for_block.last_thread;
- fprintf(keycache_dump_file, "queue of threads waiting for block\n");
- if (thread)
- do
- {
- thread=thread->next;
- hash_link= (HASH_LINK *) thread->opt_info;
- fprintf(keycache_dump_file,
- "thread:%u hash_link:%u (file,filepos)=(%u,%lu)\n",
- thread->id, (uint) HASH_LINK_NUMBER(hash_link),
- (uint) hash_link->file,(ulong) hash_link->diskpos);
- if (++i == MAX_QUEUE_LEN)
- break;
- }
- while (thread != last);
-
- for (i=0 ; i< keycache->blocks_used ; i++)
- {
- int j;
- block= &keycache->block_root[i];
- hash_link= block->hash_link;
- fprintf(keycache_dump_file,
- "block:%u hash_link:%d status:%x #requests=%u waiting_for_readers:%d\n",
- i, (int) (hash_link ? HASH_LINK_NUMBER(hash_link) : -1),
- block->status, block->requests, block->condvar ? 1 : 0);
- for (j=0 ; j < 2; j++)
- {
- KEYCACHE_WQUEUE *wqueue=&block->wqueue[j];
- thread= last= wqueue->last_thread;
- fprintf(keycache_dump_file, "queue #%d\n", j);
- if (thread)
- {
- do
- {
- thread=thread->next;
- fprintf(keycache_dump_file,
- "thread:%u\n", thread->id);
- if (++i == MAX_QUEUE_LEN)
- break;
- }
- while (thread != last);
- }
- }
- }
- fprintf(keycache_dump_file, "LRU chain:");
- block= keycache= used_last;
- if (block)
- {
- do
- {
- block= block->next_used;
- fprintf(keycache_dump_file,
- "block:%u, ", BLOCK_NUMBER(block));
- }
- while (block != keycache->used_last);
- }
- fprintf(keycache_dump_file, "\n");
-
- fclose(keycache_dump_file);
-}
-
-#endif /* defined(KEYCACHE_TIMEOUT) */
-
-#if defined(KEYCACHE_TIMEOUT) && !defined(__WIN__)
-
-
-static int keycache_pthread_cond_wait(mysql_cond_t *cond,
- mysql_mutex_t *mutex)
-{
- int rc;
- struct timeval now; /* time when we started waiting */
- struct timespec timeout; /* timeout value for the wait function */
- struct timezone tz;
-#if defined(KEYCACHE_DEBUG)
- int cnt=0;
-#endif
-
- /* Get current time */
- gettimeofday(&now, &tz);
- /* Prepare timeout value */
- timeout.tv_sec= now.tv_sec + KEYCACHE_TIMEOUT;
- /*
- timeval uses microseconds.
- timespec uses nanoseconds.
- 1 nanosecond = 1000 micro seconds
- */
- timeout.tv_nsec= now.tv_usec * 1000;
- KEYCACHE_THREAD_TRACE_END("started waiting");
-#if defined(KEYCACHE_DEBUG)
- cnt++;
- if (cnt % 100 == 0)
- fprintf(keycache_debug_log, "waiting...\n");
- fflush(keycache_debug_log);
-#endif
- rc= mysql_cond_timedwait(cond, mutex, &timeout);
- KEYCACHE_THREAD_TRACE_BEGIN("finished waiting");
- if (rc == ETIMEDOUT || rc == ETIME)
- {
-#if defined(KEYCACHE_DEBUG)
- fprintf(keycache_debug_log,"aborted by keycache timeout\n");
- fclose(keycache_debug_log);
- abort();
-#endif
- keycache_dump();
- }
-
-#if defined(KEYCACHE_DEBUG)
- KEYCACHE_DBUG_ASSERT(rc != ETIMEDOUT);
-#else
- assert(rc != ETIMEDOUT);
-#endif
- return rc;
-}
-#else
-#if defined(KEYCACHE_DEBUG)
-static int keycache_pthread_cond_wait(mysql_cond_t *cond,
- mysql_mutex_t *mutex)
-{
- int rc;
- KEYCACHE_THREAD_TRACE_END("started waiting");
- rc= mysql_cond_wait(cond, mutex);
- KEYCACHE_THREAD_TRACE_BEGIN("finished waiting");
- return rc;
-}
-#endif
-#endif /* defined(KEYCACHE_TIMEOUT) && !defined(__WIN__) */
-
-#if defined(KEYCACHE_DEBUG)
-
-
-static int keycache_pthread_mutex_lock(mysql_mutex_t *mutex)
-{
- int rc;
- rc= mysql_mutex_lock(mutex);
- KEYCACHE_THREAD_TRACE_BEGIN("");
- return rc;
-}
-
-
-static void keycache_pthread_mutex_unlock(mysql_mutex_t *mutex)
-{
- KEYCACHE_THREAD_TRACE_END("");
- mysql_mutex_unlock(mutex);
-}
-
-
-static int keycache_pthread_cond_signal(mysql_cond_t *cond)
-{
- int rc;
- KEYCACHE_THREAD_TRACE("signal");
- rc= mysql_cond_signal(cond);
- return rc;
-}
-
-
-#if defined(KEYCACHE_DEBUG_LOG)
-
-
-static void keycache_debug_print(const char * fmt,...)
-{
- va_list args;
- va_start(args,fmt);
- if (keycache_debug_log)
- {
- (void) vfprintf(keycache_debug_log, fmt, args);
- (void) fputc('\n',keycache_debug_log);
- }
- va_end(args);
-}
-#endif /* defined(KEYCACHE_DEBUG_LOG) */
-
-#if defined(KEYCACHE_DEBUG_LOG)
-
-
-void keycache_debug_log_close(void)
-{
- if (keycache_debug_log)
- fclose(keycache_debug_log);
-}
-#endif /* defined(KEYCACHE_DEBUG_LOG) */
-
-#endif /* defined(KEYCACHE_DEBUG) */
-
-#if !defined(DBUG_OFF)
-#define F_B_PRT(_f_, _v_) DBUG_PRINT("assert_fail", (_f_, _v_))
-
-static int fail_block(BLOCK_LINK *block)
-{
- F_B_PRT("block->next_used: %lx\n", (ulong) block->next_used);
- F_B_PRT("block->prev_used: %lx\n", (ulong) block->prev_used);
- F_B_PRT("block->next_changed: %lx\n", (ulong) block->next_changed);
- F_B_PRT("block->prev_changed: %lx\n", (ulong) block->prev_changed);
- F_B_PRT("block->hash_link: %lx\n", (ulong) block->hash_link);
- F_B_PRT("block->status: %u\n", block->status);
- F_B_PRT("block->length: %u\n", block->length);
- F_B_PRT("block->offset: %u\n", block->offset);
- F_B_PRT("block->requests: %u\n", block->requests);
- F_B_PRT("block->temperature: %u\n", block->temperature);
- return 0; /* Let the assert fail. */
-}
-
-static int fail_hlink(HASH_LINK *hlink)
-{
- F_B_PRT("hlink->next: %lx\n", (ulong) hlink->next);
- F_B_PRT("hlink->prev: %lx\n", (ulong) hlink->prev);
- F_B_PRT("hlink->block: %lx\n", (ulong) hlink->block);
- F_B_PRT("hlink->diskpos: %lu\n", (ulong) hlink->diskpos);
- F_B_PRT("hlink->file: %d\n", hlink->file);
- return 0; /* Let the assert fail. */
-}
-
-static int cache_empty(KEY_CACHE *keycache)
-{
- int errcnt= 0;
- int idx;
- if (keycache->disk_blocks <= 0)
- return 1;
- for (idx= 0; idx < keycache->disk_blocks; idx++)
- {
- BLOCK_LINK *block= keycache->block_root + idx;
- if (block->status || block->requests || block->hash_link)
- {
- fprintf(stderr, "block index: %u\n", idx);
- fail_block(block);
- errcnt++;
- }
- }
- for (idx= 0; idx < keycache->hash_links; idx++)
- {
- HASH_LINK *hash_link= keycache->hash_link_root + idx;
- if (hash_link->requests || hash_link->block)
- {
- fprintf(stderr, "hash_link index: %u\n", idx);
- fail_hlink(hash_link);
- errcnt++;
- }
- }
- if (errcnt)
- {
- fprintf(stderr, "blocks: %d used: %lu\n",
- keycache->disk_blocks, keycache->blocks_used);
- fprintf(stderr, "hash_links: %d used: %d\n",
- keycache->hash_links, keycache->hash_links_used);
- fprintf(stderr, "\n");
- }
- return !errcnt;
-}
-#endif
-
diff --git a/dep/mysqllite/mysys/mf_keycaches.c b/dep/mysqllite/mysys/mf_keycaches.c
deleted file mode 100644
index 93b7eab4561..00000000000
--- a/dep/mysqllite/mysys/mf_keycaches.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/* Copyright (C) 2003 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 */
-
-/*
- Handling of multiple key caches
-
- The idea is to have a thread safe hash on the table name,
- with a default key cache value that is returned if the table name is not in
- the cache.
-*/
-
-#include "mysys_priv.h"
-#include <keycache.h>
-#include <hash.h>
-#include <m_string.h>
-
-/*****************************************************************************
- General functions to handle SAFE_HASH objects.
-
- A SAFE_HASH object is used to store the hash, the mutex and default value
- needed by the rest of the key cache code.
- This is a separate struct to make it easy to later reuse the code for other
- purposes
-
- All entries are linked in a list to allow us to traverse all elements
- and delete selected ones. (HASH doesn't allow any easy ways to do this).
-*****************************************************************************/
-
-/*
- Struct to store a key and pointer to object
-*/
-
-typedef struct st_safe_hash_entry
-{
- uchar *key;
- uint length;
- uchar *data;
- struct st_safe_hash_entry *next, **prev;
-} SAFE_HASH_ENTRY;
-
-
-typedef struct st_safe_hash_with_default
-{
- rw_lock_t mutex;
- HASH hash;
- uchar *default_value;
- SAFE_HASH_ENTRY *root;
-} SAFE_HASH;
-
-
-/*
- Free a SAFE_HASH_ENTRY
-
- This function is called by the hash object on delete
-*/
-
-static void safe_hash_entry_free(SAFE_HASH_ENTRY *entry)
-{
- DBUG_ENTER("free_assign_entry");
- my_free(entry);
- DBUG_VOID_RETURN;
-}
-
-
-/* Get key and length for a SAFE_HASH_ENTRY */
-
-static uchar *safe_hash_entry_get(SAFE_HASH_ENTRY *entry, size_t *length,
- my_bool not_used __attribute__((unused)))
-{
- *length=entry->length;
- return (uchar*) entry->key;
-}
-
-
-/*
- Init a SAFE_HASH object
-
- SYNOPSIS
- safe_hash_init()
- hash safe_hash handler
- elements Expected max number of elements
- default_value default value
-
- NOTES
- In case of error we set hash->default_value to 0 to allow one to call
- safe_hash_free on an object that couldn't be initialized.
-
- RETURN
- 0 ok
- 1 error
-*/
-
-static my_bool safe_hash_init(SAFE_HASH *hash, uint elements,
- uchar *default_value)
-{
- DBUG_ENTER("safe_hash");
- if (my_hash_init(&hash->hash, &my_charset_bin, elements,
- 0, 0, (my_hash_get_key) safe_hash_entry_get,
- (void (*)(void*)) safe_hash_entry_free, 0))
- {
- hash->default_value= 0;
- DBUG_RETURN(1);
- }
- my_rwlock_init(&hash->mutex, 0);
- hash->default_value= default_value;
- hash->root= 0;
- DBUG_RETURN(0);
-}
-
-
-/*
- Free a SAFE_HASH object
-
- NOTES
- This is safe to call on any object that has been sent to safe_hash_init()
-*/
-
-static void safe_hash_free(SAFE_HASH *hash)
-{
- /*
- Test if safe_hash_init succeeded. This will also guard us against multiple
- free calls.
- */
- if (hash->default_value)
- {
- my_hash_free(&hash->hash);
- rwlock_destroy(&hash->mutex);
- hash->default_value=0;
- }
-}
-
-/*
- Return the value stored for a key or default value if no key
-*/
-
-static uchar *safe_hash_search(SAFE_HASH *hash, const uchar *key, uint length)
-{
- uchar *result;
- DBUG_ENTER("safe_hash_search");
- rw_rdlock(&hash->mutex);
- result= my_hash_search(&hash->hash, key, length);
- rw_unlock(&hash->mutex);
- if (!result)
- result= hash->default_value;
- else
- result= ((SAFE_HASH_ENTRY*) result)->data;
- DBUG_PRINT("exit",("data: 0x%lx", (long) result));
- DBUG_RETURN(result);
-}
-
-
-/*
- Associate a key with some data
-
- SYONOPSIS
- safe_hash_set()
- hash Hash handle
- key key (path to table etc..)
- length Length of key
- data data to to associate with the data
-
- NOTES
- This can be used both to insert a new entry and change an existing
- entry.
- If one associates a key with the default key cache, the key is deleted
-
- RETURN
- 0 ok
- 1 error (Can only be EOM). In this case my_message() is called.
-*/
-
-static my_bool safe_hash_set(SAFE_HASH *hash, const uchar *key, uint length,
- uchar *data)
-{
- SAFE_HASH_ENTRY *entry;
- my_bool error= 0;
- DBUG_ENTER("safe_hash_set");
- DBUG_PRINT("enter",("key: %.*s data: 0x%lx", length, key, (long) data));
-
- rw_wrlock(&hash->mutex);
- entry= (SAFE_HASH_ENTRY*) my_hash_search(&hash->hash, key, length);
-
- if (data == hash->default_value)
- {
- /*
- The key is to be associated with the default entry. In this case
- we can just delete the entry (if it existed) from the hash as a
- search will return the default entry
- */
- if (!entry) /* nothing to do */
- goto end;
- /* unlink entry from list */
- if ((*entry->prev= entry->next))
- entry->next->prev= entry->prev;
- my_hash_delete(&hash->hash, (uchar*) entry);
- goto end;
- }
- if (entry)
- {
- /* Entry existed; Just change the pointer to point at the new data */
- entry->data= data;
- }
- else
- {
- if (!(entry= (SAFE_HASH_ENTRY *) my_malloc(sizeof(*entry) + length,
- MYF(MY_WME))))
- {
- error= 1;
- goto end;
- }
- entry->key= (uchar*) (entry +1);
- memcpy((char*) entry->key, (char*) key, length);
- entry->length= length;
- entry->data= data;
- /* Link entry to list */
- if ((entry->next= hash->root))
- entry->next->prev= &entry->next;
- entry->prev= &hash->root;
- hash->root= entry;
- if (my_hash_insert(&hash->hash, (uchar*) entry))
- {
- /* This can only happen if hash got out of memory */
- my_free(entry);
- error= 1;
- goto end;
- }
- }
-
-end:
- rw_unlock(&hash->mutex);
- DBUG_RETURN(error);
-}
-
-
-/*
- Change all entres with one data value to another data value
-
- SYONOPSIS
- safe_hash_change()
- hash Hash handle
- old_data Old data
- new_data Change all 'old_data' to this
-
- NOTES
- We use the linked list to traverse all elements in the hash as
- this allows us to delete elements in the case where 'new_data' is the
- default value.
-*/
-
-static void safe_hash_change(SAFE_HASH *hash, uchar *old_data, uchar *new_data)
-{
- SAFE_HASH_ENTRY *entry, *next;
- DBUG_ENTER("safe_hash_set");
-
- rw_wrlock(&hash->mutex);
-
- for (entry= hash->root ; entry ; entry= next)
- {
- next= entry->next;
- if (entry->data == old_data)
- {
- if (new_data == hash->default_value)
- {
- if ((*entry->prev= entry->next))
- entry->next->prev= entry->prev;
- my_hash_delete(&hash->hash, (uchar*) entry);
- }
- else
- entry->data= new_data;
- }
- }
-
- rw_unlock(&hash->mutex);
- DBUG_VOID_RETURN;
-}
-
-
-/*****************************************************************************
- Functions to handle the key cache objects
-*****************************************************************************/
-
-/* Variable to store all key cache objects */
-static SAFE_HASH key_cache_hash;
-
-
-my_bool multi_keycache_init(void)
-{
- return safe_hash_init(&key_cache_hash, 16, (uchar*) dflt_key_cache);
-}
-
-
-void multi_keycache_free(void)
-{
- safe_hash_free(&key_cache_hash);
-}
-
-/*
- Get a key cache to be used for a specific table.
-
- SYNOPSIS
- multi_key_cache_search()
- key key to find (usually table path)
- uint length Length of key.
-
- NOTES
- This function is coded in such a way that we will return the
- default key cache even if one never called multi_keycache_init.
- This will ensure that it works with old MyISAM clients.
-
- RETURN
- key cache to use
-*/
-
-KEY_CACHE *multi_key_cache_search(uchar *key, uint length)
-{
- if (!key_cache_hash.hash.records)
- return dflt_key_cache;
- return (KEY_CACHE*) safe_hash_search(&key_cache_hash, key, length);
-}
-
-
-/*
- Assosiate a key cache with a key
-
-
- SYONOPSIS
- multi_key_cache_set()
- key key (path to table etc..)
- length Length of key
- key_cache cache to assococite with the table
-
- NOTES
- This can be used both to insert a new entry and change an existing
- entry
-*/
-
-
-my_bool multi_key_cache_set(const uchar *key, uint length,
- KEY_CACHE *key_cache)
-{
- return safe_hash_set(&key_cache_hash, key, length, (uchar*) key_cache);
-}
-
-
-void multi_key_cache_change(KEY_CACHE *old_data,
- KEY_CACHE *new_data)
-{
- safe_hash_change(&key_cache_hash, (uchar*) old_data, (uchar*) new_data);
-}
diff --git a/dep/mysqllite/mysys/mf_loadpath.c b/dep/mysqllite/mysys/mf_loadpath.c
deleted file mode 100644
index 9350babc176..00000000000
--- a/dep/mysqllite/mysys/mf_loadpath.c
+++ /dev/null
@@ -1,55 +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 <m_string.h>
-
- /* Returns full load-path for a file. to may be = path */
- /* if path is a hard-path return path */
- /* if path starts with home-dir return path */
- /* if path starts with current dir or parent-dir unpack path */
- /* if there is no path, prepend with own_path_prefix if given */
- /* else unpack path according to current dir */
-
-char * my_load_path(char * to, const char *path,
- const char *own_path_prefix)
-{
- char buff[FN_REFLEN];
- int is_cur;
- DBUG_ENTER("my_load_path");
- DBUG_PRINT("enter",("path: %s prefix: %s",path,
- own_path_prefix ? own_path_prefix : ""));
-
- if ((path[0] == FN_HOMELIB && path[1] == FN_LIBCHAR) ||
- test_if_hard_path(path))
- (void) strnmov(buff, path, FN_REFLEN);
- else if ((is_cur=(path[0] == FN_CURLIB && path[1] == FN_LIBCHAR)) ||
- (is_prefix(path,FN_PARENTDIR)) ||
- ! own_path_prefix)
- {
- if (is_cur)
- is_cur=2; /* Remove current dir */
- if (! my_getwd(buff,(uint) (FN_REFLEN-strlen(path)+is_cur),MYF(0)))
- (void) strncat(buff, path+is_cur, FN_REFLEN-1);
- else
- (void) strnmov(buff, path, FN_REFLEN); /* Return org file name */
- }
- else
- (void) strxnmov(buff, FN_REFLEN, own_path_prefix, path, NullS);
- strnmov(to, buff, FN_REFLEN);
- to[FN_REFLEN-1]= '\0';
- DBUG_PRINT("exit",("to: %s",to));
- DBUG_RETURN(to);
-} /* my_load_path */
diff --git a/dep/mysqllite/mysys/mf_pack.c b/dep/mysqllite/mysys/mf_pack.c
deleted file mode 100644
index 292cd8c0454..00000000000
--- a/dep/mysqllite/mysys/mf_pack.c
+++ /dev/null
@@ -1,460 +0,0 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
-
- 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 <m_string.h>
-#ifdef HAVE_PWD_H
-#include <pwd.h>
-#endif
-
-static char * expand_tilde(char **path);
-
- /* Pack a dirname ; Changes HOME to ~/ and current dev to ./ */
- /* from is a dirname (from dirname() ?) ending with FN_LIBCHAR */
- /* to may be == from */
-
-void pack_dirname(char * to, const char *from)
-{
- int cwd_err;
- size_t d_length,length,UNINIT_VAR(buff_length);
- char * start;
- char buff[FN_REFLEN];
- DBUG_ENTER("pack_dirname");
-
- (void) intern_filename(to,from); /* Change to intern name */
-
-#ifdef FN_DEVCHAR
- if ((start=strrchr(to,FN_DEVCHAR)) != 0) /* Skip device part */
- start++;
- else
-#endif
- start=to;
-
- if (!(cwd_err= my_getwd(buff,FN_REFLEN,MYF(0))))
- {
- buff_length= strlen(buff);
- d_length= (size_t) (start-to);
- if ((start == to ||
- (buff_length == d_length && !memcmp(buff,start,d_length))) &&
- *start != FN_LIBCHAR && *start)
- { /* Put current dir before */
- bchange((uchar*) to, d_length, (uchar*) buff, buff_length, strlen(to)+1);
- }
- }
-
- if ((d_length= cleanup_dirname(to,to)) != 0)
- {
- length=0;
- if (home_dir)
- {
- length= strlen(home_dir);
- if (home_dir[length-1] == FN_LIBCHAR)
- length--; /* Don't test last '/' */
- }
- if (length > 1 && length < d_length)
- { /* test if /xx/yy -> ~/yy */
- if (memcmp(to,home_dir,length) == 0 && to[length] == FN_LIBCHAR)
- {
- to[0]=FN_HOMELIB; /* Filename begins with ~ */
- (void) strmov_overlapp(to+1,to+length);
- }
- }
- if (! cwd_err)
- { /* Test if cwd is ~/... */
- if (length > 1 && length < buff_length)
- {
- if (memcmp(buff,home_dir,length) == 0 && buff[length] == FN_LIBCHAR)
- {
- buff[0]=FN_HOMELIB;
- (void) strmov_overlapp(buff+1,buff+length);
- }
- }
- if (is_prefix(to,buff))
- {
- length= strlen(buff);
- if (to[length])
- (void) strmov_overlapp(to,to+length); /* Remove everything before */
- else
- {
- to[0]= FN_CURLIB; /* Put ./ instead of cwd */
- to[1]= FN_LIBCHAR;
- to[2]= '\0';
- }
- }
- }
- }
- DBUG_PRINT("exit",("to: '%s'",to));
- DBUG_VOID_RETURN;
-} /* pack_dirname */
-
-
-/*
- remove unwanted chars from dirname
-
- 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
-*/
-
-size_t cleanup_dirname(register char *to, const char *from)
-{
- reg5 size_t length;
- reg2 char * pos;
- reg3 char * from_ptr;
- reg4 char * start;
- char parent[5], /* for "FN_PARENTDIR" */
- buff[FN_REFLEN+1],*end_parentdir;
-#ifdef BACKSLASH_MBTAIL
- CHARSET_INFO *fs= fs_character_set();
-#endif
- DBUG_ENTER("cleanup_dirname");
- DBUG_PRINT("enter",("from: '%s'",from));
-
- start=buff;
- from_ptr=(char *) from;
-#ifdef FN_DEVCHAR
- if ((pos=strrchr(from_ptr,FN_DEVCHAR)) != 0)
- { /* Skip device part */
- length=(size_t) (pos-from_ptr)+1;
- start=strnmov(buff,from_ptr,length); from_ptr+=length;
- }
-#endif
-
- parent[0]=FN_LIBCHAR;
- length=(size_t) (strmov(parent+1,FN_PARENTDIR)-parent);
- for (pos=start ; (*pos= *from_ptr++) != 0 ; pos++)
- {
-#ifdef BACKSLASH_MBTAIL
- uint l;
- if (use_mb(fs) && (l= my_ismbchar(fs, from_ptr - 1, from_ptr + 2)))
- {
- for (l-- ; l ; *++pos= *from_ptr++, l--);
- start= pos + 1; /* Don't look inside multi-byte char */
- continue;
- }
-#endif
- if (*pos == '/')
- *pos = FN_LIBCHAR;
- if (*pos == FN_LIBCHAR)
- {
- if ((size_t) (pos-start) > length && memcmp(pos-length,parent,length) == 0)
- { /* If .../../; skip prev */
- pos-=length;
- if (pos != start)
- { /* not /../ */
- pos--;
- if (*pos == FN_HOMELIB && (pos == start || pos[-1] == FN_LIBCHAR))
- {
- if (!home_dir)
- {
- pos+=length+1; /* Don't unpack ~/.. */
- continue;
- }
- pos=strmov(buff,home_dir)-1; /* Unpacks ~/.. */
- if (*pos == FN_LIBCHAR)
- pos--; /* home ended with '/' */
- }
- if (*pos == FN_CURLIB && (pos == start || pos[-1] == FN_LIBCHAR))
- {
- if (my_getwd(curr_dir,FN_REFLEN,MYF(0)))
- {
- pos+=length+1; /* Don't unpack ./.. */
- continue;
- }
- pos=strmov(buff,curr_dir)-1; /* Unpacks ./.. */
- if (*pos == FN_LIBCHAR)
- pos--; /* home ended with '/' */
- }
- end_parentdir=pos;
- while (pos >= start && *pos != FN_LIBCHAR) /* remove prev dir */
- pos--;
- if (pos[1] == FN_HOMELIB ||
- (pos > start && memcmp(pos, parent, length) == 0))
- { /* Don't remove ~user/ */
- pos=strmov(end_parentdir+1,parent);
- *pos=FN_LIBCHAR;
- continue;
- }
- }
- }
- else if ((size_t) (pos-start) == length-1 &&
- !memcmp(start,parent+1,length-1))
- start=pos; /* Starts with "../" */
- else if (pos-start > 0 && pos[-1] == FN_LIBCHAR)
- {
-#ifdef FN_NETWORK_DRIVES
- if (pos-start != 1)
-#endif
- pos--; /* Remove dupplicate '/' */
- }
- else if (pos-start > 1 && pos[-1] == FN_CURLIB && pos[-2] == FN_LIBCHAR)
- pos-=2; /* Skip /./ */
- else if (pos > buff+1 && pos[-1] == FN_HOMELIB && pos[-2] == FN_LIBCHAR)
- { /* Found ..../~/ */
- buff[0]=FN_HOMELIB;
- buff[1]=FN_LIBCHAR;
- start=buff; pos=buff+1;
- }
- }
- }
- (void) strmov(to,buff);
- DBUG_PRINT("exit",("to: '%s'",to));
- DBUG_RETURN((size_t) (pos-buff));
-} /* cleanup_dirname */
-
-
-/*
- On system where you don't have symbolic links, the following
- code will allow you to create a file:
- directory-name.sym that should contain the real path
- to the directory. This will be used if the directory name
- doesn't exists
-*/
-
-
-my_bool my_use_symdir=0; /* Set this if you want to use symdirs */
-
-#ifdef USE_SYMDIR
-void symdirget(char *dir)
-{
- char buff[FN_REFLEN+1];
- char *pos=strend(dir);
- if (dir[0] && pos[-1] != FN_DEVCHAR && my_access(dir, F_OK))
- {
- File file;
- size_t length;
- char temp= *(--pos); /* May be "/" or "\" */
- strmov(pos,".sym");
- file= my_open(dir, O_RDONLY, MYF(0));
- *pos++=temp; *pos=0; /* Restore old filename */
- if (file >= 0)
- {
- if ((length= my_read(file, buff, sizeof(buff) - 1, MYF(0))) > 0)
- {
- for (pos= buff + length ;
- pos > buff && (iscntrl(pos[-1]) || isspace(pos[-1])) ;
- pos --);
-
- /* Ensure that the symlink ends with the directory symbol */
- if (pos == buff || pos[-1] != FN_LIBCHAR)
- *pos++=FN_LIBCHAR;
-
- strmake(dir,buff, (size_t) (pos-buff));
- }
- my_close(file, MYF(0));
- }
- }
-}
-#endif /* USE_SYMDIR */
-
-
-/**
- Convert a directory name to a format which can be compared as strings
-
- @param to result buffer, FN_REFLEN chars in length; may be == from
- @param from 'packed' directory name, in whatever format
- @returns size of the normalized name
-
- @details
- - Ensures that last char is FN_LIBCHAR, unless it is FN_DEVCHAR
- - Uses cleanup_dirname
-
- It does *not* expand ~/ (although, see cleanup_dirname). Nor does it do
- any case folding. All case-insensitive normalization should be done by
- the caller.
-*/
-
-size_t normalize_dirname(char *to, const char *from)
-{
- size_t length;
- char buff[FN_REFLEN];
- DBUG_ENTER("normalize_dirname");
-
- /*
- Despite the name, this actually converts the name to the system's
- format (TODO: name this properly).
- */
- (void) intern_filename(buff, from);
- length= strlen(buff); /* Fix that '/' is last */
- if (length &&
-#ifdef FN_DEVCHAR
- buff[length - 1] != FN_DEVCHAR &&
-#endif
- buff[length - 1] != FN_LIBCHAR && buff[length - 1] != '/')
- {
- /* we need reserve 2 bytes for the trailing slash and the zero */
- if (length >= sizeof (buff) - 1)
- length= sizeof (buff) - 2;
- buff[length]= FN_LIBCHAR;
- buff[length + 1]= '\0';
- }
-
- length=cleanup_dirname(to, buff);
-
- DBUG_RETURN(length);
-}
-
-
-/**
- Fixes a directory name so that can be used by open()
-
- @param to Result buffer, FN_REFLEN characters. May be == from
- @param from 'Packed' directory name (may contain ~)
-
- @details
- - Uses normalize_dirname()
- - Expands ~/... to home_dir/...
- - Resolves MySQL's fake "foo.sym" symbolic directory names (if USE_SYMDIR)
- - Changes a UNIX filename to system filename (replaces / with \ on windows)
-
- @returns
- Length of new directory name (= length of to)
-*/
-
-size_t unpack_dirname(char * to, const char *from)
-{
- size_t length, h_length;
- char buff[FN_REFLEN+1+4],*suffix,*tilde_expansion;
- DBUG_ENTER("unpack_dirname");
-
- length= normalize_dirname(buff, from);
-
- if (buff[0] == FN_HOMELIB)
- {
- suffix=buff+1; tilde_expansion=expand_tilde(&suffix);
- if (tilde_expansion)
- {
- length-= (size_t) (suffix-buff)-1;
- if (length+(h_length= strlen(tilde_expansion)) <= FN_REFLEN)
- {
- if ((h_length > 0) && (tilde_expansion[h_length-1] == FN_LIBCHAR))
- h_length--;
- if (buff+h_length < suffix)
- bmove(buff+h_length,suffix,length);
- else
- bmove_upp((uchar*) buff+h_length+length, (uchar*) suffix+length, length);
- bmove(buff,tilde_expansion,h_length);
- }
- }
- }
-#ifdef USE_SYMDIR
- if (my_use_symdir)
- symdirget(buff);
-#endif
- DBUG_RETURN(system_filename(to,buff)); /* Fix for open */
-} /* unpack_dirname */
-
-
- /* Expand tilde to home or user-directory */
- /* Path is reset to point at FN_LIBCHAR after ~xxx */
-
-static char * expand_tilde(char **path)
-{
- if (path[0][0] == FN_LIBCHAR)
- return home_dir; /* ~/ expanded to home */
-#ifdef HAVE_GETPWNAM
- {
- char *str,save;
- struct passwd *user_entry;
-
- if (!(str=strchr(*path,FN_LIBCHAR)))
- str=strend(*path);
- save= *str; *str= '\0';
- user_entry=getpwnam(*path);
- *str=save;
- endpwent();
- if (user_entry)
- {
- *path=str;
- return user_entry->pw_dir;
- }
- }
-#endif
- return (char *) 0;
-}
-
-
-/*
- Fix filename so it can be used by open, create
-
- SYNOPSIS
- unpack_filename()
- to Store result here. Must be at least of size FN_REFLEN.
- from Filename in unix format (with ~)
-
- RETURN
- # length of to
-
- NOTES
- to may be == from
- ~ will only be expanded if total length < FN_REFLEN
-*/
-
-
-size_t unpack_filename(char * to, const char *from)
-{
- size_t length, n_length, buff_length;
- char buff[FN_REFLEN];
- DBUG_ENTER("unpack_filename");
-
- length=dirname_part(buff, from, &buff_length);/* copy & convert dirname */
- n_length=unpack_dirname(buff,buff);
- if (n_length+strlen(from+length) < FN_REFLEN)
- {
- (void) strmov(buff+n_length,from+length);
- length= system_filename(to,buff); /* Fix to usably filename */
- }
- else
- length= system_filename(to,from); /* Fix to usably filename */
- DBUG_RETURN(length);
-} /* unpack_filename */
-
-
- /* Convert filename (unix standard) to system standard */
- /* Used before system command's like open(), create() .. */
- /* Returns used length of to; total length should be FN_REFLEN */
-
-size_t system_filename(char *to, const char *from)
-{
- return (size_t) (strmake(to,from,FN_REFLEN-1)-to);
-}
-
- /* Fix a filename to intern (UNIX format) */
-
-char *intern_filename(char *to, const char *from)
-{
- size_t length, to_length;
- char buff[FN_REFLEN];
- if (from == to)
- { /* Dirname may destroy from */
- strmov(buff,from);
- from=buff;
- }
- length= dirname_part(to, from, &to_length); /* Copy dirname & fix chars */
- (void) strmov(to + to_length,from+length);
- return (to);
-} /* intern_filename */
diff --git a/dep/mysqllite/mysys/mf_path.c b/dep/mysqllite/mysys/mf_path.c
deleted file mode 100644
index 92cb62e6827..00000000000
--- a/dep/mysqllite/mysys/mf_path.c
+++ /dev/null
@@ -1,120 +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 <m_string.h>
-
-static char *find_file_in_path(char *to,const char *name);
-
- /* Finds where program can find it's files.
- pre_pathname is found by first locking at progname (argv[0]).
- if progname contains path the path is returned.
- else if progname is found in path, return it
- else if progname is given and POSIX environment variable "_" is set
- then path is taken from "_".
- If filename doesn't contain a path append MY_BASEDIR_VERSION or
- MY_BASEDIR if defined, else append "/my/running".
- own_path_name_part is concatinated to result.
- my_path puts result in to and returns to */
-
-char * my_path(char * to, const char *progname,
- const char *own_pathname_part)
-{
- char *start, *end, *prog;
- size_t to_length;
- DBUG_ENTER("my_path");
-
- start=to; /* Return this */
- if (progname && (dirname_part(to, progname, &to_length) ||
- find_file_in_path(to,progname) ||
- ((prog=getenv("_")) != 0 &&
- dirname_part(to, prog, &to_length))))
- {
- (void) intern_filename(to,to);
- if (!test_if_hard_path(to))
- {
- if (!my_getwd(curr_dir,FN_REFLEN,MYF(0)))
- bchange((uchar*) to, 0, (uchar*) curr_dir, strlen(curr_dir), strlen(to)+1);
- }
- }
- else
- {
- if ((end = getenv("MY_BASEDIR_VERSION")) == 0 &&
- (end = getenv("MY_BASEDIR")) == 0)
- {
-#ifdef DEFAULT_BASEDIR
- end= (char*) DEFAULT_BASEDIR;
-#else
- end= (char*) "/my/";
-#endif
- }
- (void) intern_filename(to,end);
- to=strend(to);
- if (to != start && to[-1] != FN_LIBCHAR)
- *to++ = FN_LIBCHAR;
- (void) strmov(to,own_pathname_part);
- }
- DBUG_PRINT("exit",("to: '%s'",start));
- DBUG_RETURN(start);
-} /* my_path */
-
-
- /* test if file without filename is found in path */
- /* Returns to if found and to has dirpart if found, else NullS */
-
-#if defined(__WIN__)
-#define F_OK 0
-#define PATH_SEP ';'
-#define PROGRAM_EXTENSION ".exe"
-#else
-#define PATH_SEP ':'
-#endif
-
-static char *find_file_in_path(char *to, const char *name)
-{
- char *path,*pos,dir[2];
- const char *ext="";
-
- if (!(path=getenv("PATH")))
- return NullS;
- dir[0]=FN_LIBCHAR; dir[1]=0;
-#ifdef PROGRAM_EXTENSION
- if (!fn_ext(name)[0])
- ext=PROGRAM_EXTENSION;
-#endif
-
- for (pos=path ; (pos=strchr(pos,PATH_SEP)) ; path= ++pos)
- {
- if (path != pos)
- {
- strxmov(strnmov(to,path,(uint) (pos-path)),dir,name,ext,NullS);
- if (!access(to,F_OK))
- {
- to[(uint) (pos-path)+1]=0; /* Return path only */
- return to;
- }
- }
- }
-#ifdef __WIN__
- to[0]=FN_CURLIB;
- strxmov(to+1,dir,name,ext,NullS);
- if (!access(to,F_OK)) /* Test in current dir */
- {
- to[2]=0; /* Leave ".\" */
- return to;
- }
-#endif
- return NullS; /* File not found */
-}
diff --git a/dep/mysqllite/mysys/mf_qsort.c b/dep/mysqllite/mysys/mf_qsort.c
deleted file mode 100644
index 4b3ecb603a6..00000000000
--- a/dep/mysqllite/mysys/mf_qsort.c
+++ /dev/null
@@ -1,216 +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 */
-
-/*
- qsort implementation optimized for comparison of pointers
- Inspired by the qsort implementations by Douglas C. Schmidt,
- and Bentley & McIlroy's "Engineering a Sort Function".
-*/
-
-
-#include "mysys_priv.h"
-#ifndef SCO
-#include <m_string.h>
-#endif
-
-/* We need to use qsort with 2 different compare functions */
-#ifdef QSORT_EXTRA_CMP_ARGUMENT
-#define CMP(A,B) ((*cmp)(cmp_argument,(A),(B)))
-#else
-#define CMP(A,B) ((*cmp)((A),(B)))
-#endif
-
-#define SWAP(A, B, size,swap_ptrs) \
-do { \
- if (swap_ptrs) \
- { \
- reg1 char **a = (char**) (A), **b = (char**) (B); \
- char *tmp = *a; *a++ = *b; *b++ = tmp; \
- } \
- else \
- { \
- reg1 char *a = (A), *b = (B); \
- reg3 char *end= a+size; \
- do \
- { \
- char tmp = *a; *a++ = *b; *b++ = tmp; \
- } while (a < end); \
- } \
-} while (0)
-
-/* Put the median in the middle argument */
-#define MEDIAN(low, mid, high) \
-{ \
- if (CMP(high,low) < 0) \
- SWAP(high, low, size, ptr_cmp); \
- if (CMP(mid, low) < 0) \
- SWAP(mid, low, size, ptr_cmp); \
- else if (CMP(high, mid) < 0) \
- SWAP(mid, high, size, ptr_cmp); \
-}
-
-/* The following node is used to store ranges to avoid recursive calls */
-
-typedef struct st_stack
-{
- char *low,*high;
-} stack_node;
-
-#define PUSH(LOW,HIGH) {stack_ptr->low = LOW; stack_ptr++->high = HIGH;}
-#define POP(LOW,HIGH) {LOW = (--stack_ptr)->low; HIGH = stack_ptr->high;}
-
-/* The following stack size is enough for ulong ~0 elements */
-#define STACK_SIZE (8 * sizeof(unsigned long int))
-#define THRESHOLD_FOR_INSERT_SORT 10
-#if defined(QSORT_TYPE_IS_VOID)
-#define SORT_RETURN return
-#else
-#define SORT_RETURN return 0
-#endif
-
-/****************************************************************************
-** 'standard' quicksort with the following extensions:
-**
-** Can be compiled with the qsort2_cmp compare function
-** Store ranges on stack to avoid recursion
-** Use insert sort on small ranges
-** Optimize for sorting of pointers (used often by MySQL)
-** Use median comparison to find partition element
-*****************************************************************************/
-
-#ifdef QSORT_EXTRA_CMP_ARGUMENT
-qsort_t my_qsort2(void *base_ptr, size_t count, size_t size, qsort2_cmp cmp,
- void *cmp_argument)
-#else
-qsort_t my_qsort(void *base_ptr, size_t count, size_t size, qsort_cmp cmp)
-#endif
-{
- char *low, *high, *pivot;
- stack_node stack[STACK_SIZE], *stack_ptr;
- my_bool ptr_cmp;
- /* Handle the simple case first */
- /* This will also make the rest of the code simpler */
- if (count <= 1)
- SORT_RETURN;
-
- low = (char*) base_ptr;
- high = low+ size * (count - 1);
- stack_ptr = stack + 1;
-#ifdef HAVE_purify
- /* The first element in the stack will be accessed for the last POP */
- stack[0].low=stack[0].high=0;
-#endif
- pivot = (char *) my_alloca((int) size);
- ptr_cmp= size == sizeof(char*) && !((low - (char*) 0)& (sizeof(char*)-1));
-
- /* The following loop sorts elements between high and low */
- do
- {
- char *low_ptr, *high_ptr, *mid;
-
- count=((size_t) (high - low) / size)+1;
- /* If count is small, then an insert sort is faster than qsort */
- if (count < THRESHOLD_FOR_INSERT_SORT)
- {
- for (low_ptr = low + size; low_ptr <= high; low_ptr += size)
- {
- char *ptr;
- for (ptr = low_ptr; ptr > low && CMP(ptr - size, ptr) > 0;
- ptr -= size)
- SWAP(ptr, ptr - size, size, ptr_cmp);
- }
- POP(low, high);
- continue;
- }
-
- /* Try to find a good middle element */
- mid= low + size * (count >> 1);
- if (count > 40) /* Must be bigger than 24 */
- {
- size_t step = size* (count / 8);
- MEDIAN(low, low + step, low+step*2);
- MEDIAN(mid - step, mid, mid+step);
- MEDIAN(high - 2 * step, high-step, high);
- /* Put best median in 'mid' */
- MEDIAN(low+step, mid, high-step);
- low_ptr = low;
- high_ptr = high;
- }
- else
- {
- MEDIAN(low, mid, high);
- /* The low and high argument are already in sorted against 'pivot' */
- low_ptr = low + size;
- high_ptr = high - size;
- }
- memcpy(pivot, mid, size);
-
- do
- {
- while (CMP(low_ptr, pivot) < 0)
- low_ptr += size;
- while (CMP(pivot, high_ptr) < 0)
- high_ptr -= size;
-
- if (low_ptr < high_ptr)
- {
- SWAP(low_ptr, high_ptr, size, ptr_cmp);
- low_ptr += size;
- high_ptr -= size;
- }
- else
- {
- if (low_ptr == high_ptr)
- {
- low_ptr += size;
- high_ptr -= size;
- }
- break;
- }
- }
- while (low_ptr <= high_ptr);
-
- /*
- Prepare for next iteration.
- Skip partitions of size 1 as these doesn't have to be sorted
- Push the larger partition and sort the smaller one first.
- This ensures that the stack is keept small.
- */
-
- if ((int) (high_ptr - low) <= 0)
- {
- if ((int) (high - low_ptr) <= 0)
- {
- POP(low, high); /* Nothing more to sort */
- }
- else
- low = low_ptr; /* Ignore small left part. */
- }
- else if ((int) (high - low_ptr) <= 0)
- high = high_ptr; /* Ignore small right part. */
- else if ((high_ptr - low) > (high - low_ptr))
- {
- PUSH(low, high_ptr); /* Push larger left part */
- low = low_ptr;
- }
- else
- {
- PUSH(low_ptr, high); /* Push larger right part */
- high = high_ptr;
- }
- } while (stack_ptr > stack);
- my_afree(pivot);
- SORT_RETURN;
-}
diff --git a/dep/mysqllite/mysys/mf_qsort2.c b/dep/mysqllite/mysys/mf_qsort2.c
deleted file mode 100644
index ca2bd1a4952..00000000000
--- a/dep/mysqllite/mysys/mf_qsort2.c
+++ /dev/null
@@ -1,19 +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 */
-
-/* qsort that sends one extra argument to the compare subrutine */
-
-#define QSORT_EXTRA_CMP_ARGUMENT
-#include "mf_qsort.c"
diff --git a/dep/mysqllite/mysys/mf_radix.c b/dep/mysqllite/mysys/mf_radix.c
deleted file mode 100644
index 582ca76b8f8..00000000000
--- a/dep/mysqllite/mysys/mf_radix.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 */
-
-/*
- Radixsort for pointers to fixed length strings.
- A very quick sort for not to long (< 20 char) strings.
- Neads a extra buffers of number_of_elements pointers but is
- 2-3 times faster than quicksort
-*/
-
-#include "mysys_priv.h"
-#include <m_string.h>
-
- /* Radixsort */
-
-void radixsort_for_str_ptr(uchar **base, uint number_of_elements, size_t size_of_element, uchar **buffer)
-{
- uchar **end,**ptr,**buffer_ptr;
- uint32 *count_ptr,*count_end,count[256];
- int pass;
-
- end=base+number_of_elements; count_end=count+256;
- for (pass=(int) size_of_element-1 ; pass >= 0 ; pass--)
- {
- bzero((uchar*) count,sizeof(uint32)*256);
- for (ptr= base ; ptr < end ; ptr++)
- count[ptr[0][pass]]++;
- if (count[0] == number_of_elements)
- goto next;
- for (count_ptr=count+1 ; count_ptr < count_end ; count_ptr++)
- {
- if (*count_ptr == number_of_elements)
- goto next;
- (*count_ptr)+= *(count_ptr-1);
- }
- for (ptr= end ; ptr-- != base ;)
- buffer[--count[ptr[0][pass]]]= *ptr;
- for (ptr=base, buffer_ptr=buffer ; ptr < end ;)
- (*ptr++) = *buffer_ptr++;
- next:;
- }
-}
diff --git a/dep/mysqllite/mysys/mf_same.c b/dep/mysqllite/mysys/mf_same.c
deleted file mode 100644
index 6738dc8051e..00000000000
--- a/dep/mysqllite/mysys/mf_same.c
+++ /dev/null
@@ -1,40 +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 */
-
-/* Kopierar biblioteksstrukturen och extensionen fr}n ett filnamn */
-
-#include "mysys_priv.h"
-#include <m_string.h>
-
- /*
- Copy directory and/or extension between filenames.
- (For the meaning of 'flag', check mf_format.c)
- 'to' may be equal to 'name'.
- Returns 'to'.
- */
-
-char * fn_same(char *to, const char *name, int flag)
-{
- char dev[FN_REFLEN];
- const char *ext;
- size_t dev_length;
- DBUG_ENTER("fn_same");
- DBUG_PRINT("enter",("to: %s name: %s flag: %d",to,name,flag));
-
- if ((ext=strrchr(name+dirname_part(dev, name, &dev_length),FN_EXTCHAR)) == 0)
- ext="";
-
- DBUG_RETURN(fn_format(to,to,dev,ext,flag));
-} /* fn_same */
diff --git a/dep/mysqllite/mysys/mf_sort.c b/dep/mysqllite/mysys/mf_sort.c
deleted file mode 100644
index a3e7465ead0..00000000000
--- a/dep/mysqllite/mysys/mf_sort.c
+++ /dev/null
@@ -1,41 +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 */
-
-/* Sort of string pointers in string-order with radix or qsort */
-
-#include "mysys_priv.h"
-#include <m_string.h>
-
-void my_string_ptr_sort(uchar *base, uint items, size_t size)
-{
-#if INT_MAX > 65536L
- uchar **ptr=0;
-
- if (size <= 20 && items >= 1000 && items < 100000 &&
- (ptr= (uchar**) my_malloc(items*sizeof(char*),MYF(0))))
- {
- radixsort_for_str_ptr((uchar**) base,items,size,ptr);
- my_free(ptr);
- }
- else
-#endif
- {
- if (size && items)
- {
- my_qsort2(base,items, sizeof(uchar*), get_ptr_compare(size),
- (void*) &size);
- }
- }
-}
diff --git a/dep/mysqllite/mysys/mf_soundex.c b/dep/mysqllite/mysys/mf_soundex.c
deleted file mode 100644
index fe30d8c81af..00000000000
--- a/dep/mysqllite/mysys/mf_soundex.c
+++ /dev/null
@@ -1,105 +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 */
-
-/****************************************************************
-* SOUNDEX ALGORITHM in C *
-* *
-* The basic Algorithm source is taken from EDN Nov. *
-* 14, 1985 pg. 36. *
-* *
-* As a test Those in Illinois will find that the *
-* first group of numbers in their drivers license *
-* number is the soundex number for their last name. *
-* *
-* RHW PC-IBBS ID. #1230 *
-* *
-* As an extension if remove_garbage is set then all non- *
-* alpha characters are skipped *
-* *
-* Note, that this implementation corresponds to the *
-* original version of the algorithm, not to the more *
-* popular "enhanced" version, described by Knuth. *
-****************************************************************/
-
-#include "mysys_priv.h"
-#include <m_ctype.h>
-#include "my_static.h"
-
-static char get_scode(CHARSET_INFO * cs, char **ptr,pbool remove_garbage);
-
- /* outputed string is 4 byte long */
- /* out_pntr can be == in_pntr */
-
-void soundex(CHARSET_INFO * cs,register char * out_pntr, char * in_pntr,
- pbool remove_garbage)
-{
- char ch,last_ch;
- reg3 char * end;
- register uchar *map=cs->to_upper;
-
- if (remove_garbage)
- {
- while (*in_pntr && !my_isalpha(cs,*in_pntr)) /* Skip pre-space */
- in_pntr++;
- }
- *out_pntr++ = map[(uchar)*in_pntr]; /* Copy first letter */
- last_ch = get_scode(cs,&in_pntr,0); /* code of the first letter */
- /* for the first 'double-letter */
- /* check. */
- end=out_pntr+3; /* Loop on input letters until */
- /* end of input (null) or output */
- /* letter code count = 3 */
-
- in_pntr++;
- while (out_pntr < end && (ch = get_scode(cs,&in_pntr,remove_garbage)) != 0)
- {
- in_pntr++;
- if ((ch != '0') && (ch != last_ch)) /* if not skipped or double */
- {
- *out_pntr++ = ch; /* letter, copy to output */
- } /* for next double-letter check */
- last_ch = ch; /* save code of last input letter */
- }
- while (out_pntr < end)
- *out_pntr++ = '0';
- *out_pntr=0; /* end string */
- return;
-} /* soundex */
-
-
- /*
- If alpha, map input letter to soundex code.
- If not alpha and remove_garbage is set then skip to next char
- else return 0
- */
-
-static char get_scode(CHARSET_INFO * cs,char **ptr, pbool remove_garbage)
-{
- uchar ch;
-
- if (remove_garbage)
- {
- while (**ptr && !my_isalpha(cs,**ptr))
- (*ptr)++;
- }
- ch=my_toupper(cs,**ptr);
- if (ch < 'A' || ch > 'Z')
- {
- if (my_isalpha(cs,ch)) /* If extended alfa (country spec) */
- return '0'; /* threat as vokal */
- return 0; /* Can't map */
- }
- return(soundex_map[ch-'A']);
-} /* get_scode */
diff --git a/dep/mysqllite/mysys/mf_tempdir.c b/dep/mysqllite/mysys/mf_tempdir.c
deleted file mode 100644
index c84987cfc96..00000000000
--- a/dep/mysqllite/mysys/mf_tempdir.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 <m_string.h>
-
-#if defined(__WIN__)
-#define DELIM ';'
-#else
-#define DELIM ':'
-#endif
-
-my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist)
-{
- char *end, *copy;
- char buff[FN_REFLEN];
- DBUG_ENTER("init_tmpdir");
- DBUG_PRINT("enter", ("pathlist: %s", pathlist ? pathlist : "NULL"));
-
- mysql_mutex_init(key_TMPDIR_mutex, &tmpdir->mutex, MY_MUTEX_INIT_FAST);
- if (my_init_dynamic_array(&tmpdir->full_list, sizeof(char*), 1, 5))
- goto err;
- if (!pathlist || !pathlist[0])
- {
- /* Get default temporary directory */
- pathlist=getenv("TMPDIR"); /* Use this if possible */
-#if defined(__WIN__)
- if (!pathlist)
- pathlist=getenv("TEMP");
- if (!pathlist)
- pathlist=getenv("TMP");
-#endif
- if (!pathlist || !pathlist[0])
- pathlist=(char*) P_tmpdir;
- }
- do
- {
- size_t length;
- end=strcend(pathlist, DELIM);
- strmake(buff, pathlist, (uint) (end-pathlist));
- length= cleanup_dirname(buff, buff);
- if (!(copy= my_strndup(buff, length, MYF(MY_WME))) ||
- insert_dynamic(&tmpdir->full_list, (uchar*) &copy))
- DBUG_RETURN(TRUE);
- pathlist=end+1;
- }
- while (*end);
- freeze_size(&tmpdir->full_list);
- tmpdir->list=(char **)tmpdir->full_list.buffer;
- tmpdir->max=tmpdir->full_list.elements-1;
- tmpdir->cur=0;
- DBUG_RETURN(FALSE);
-
-err:
- delete_dynamic(&tmpdir->full_list); /* Safe to free */
- mysql_mutex_destroy(&tmpdir->mutex);
- DBUG_RETURN(TRUE);
-}
-
-
-char *my_tmpdir(MY_TMPDIR *tmpdir)
-{
- char *dir;
- if (!tmpdir->max)
- return tmpdir->list[0];
- mysql_mutex_lock(&tmpdir->mutex);
- dir=tmpdir->list[tmpdir->cur];
- tmpdir->cur= (tmpdir->cur == tmpdir->max) ? 0 : tmpdir->cur+1;
- mysql_mutex_unlock(&tmpdir->mutex);
- return dir;
-}
-
-void free_tmpdir(MY_TMPDIR *tmpdir)
-{
- uint i;
- if (!tmpdir->full_list.elements)
- return;
- for (i=0; i<=tmpdir->max; i++)
- my_free(tmpdir->list[i]);
- delete_dynamic(&tmpdir->full_list);
- mysql_mutex_destroy(&tmpdir->mutex);
-}
-
diff --git a/dep/mysqllite/mysys/mf_tempfile.c b/dep/mysqllite/mysys/mf_tempfile.c
deleted file mode 100644
index e85124fb4c3..00000000000
--- a/dep/mysqllite/mysys/mf_tempfile.c
+++ /dev/null
@@ -1,177 +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 <m_string.h>
-#include "my_static.h"
-#include "mysys_err.h"
-#include <errno.h>
-#ifdef HAVE_PATHS_H
-#include <paths.h>
-#endif
-
-
-
-/*
- @brief
- Create a temporary file with unique name in a given directory
-
- @details
- create_temp_file
- to pointer to buffer where temporary filename will be stored
- dir directory where to create the file
- prefix prefix the filename with this
- mode Flags to use for my_create/my_open
- MyFlags Magic flags
-
- @return
- File descriptor of opened file if success
- -1 and sets errno if fails.
-
- @note
- The behaviour of this function differs a lot between
- implementation, it's main use is to generate a file with
- a name that does not already exist.
-
- When passing O_TEMPORARY flag in "mode" the file should
- be automatically deleted
-
- The implementation using mkstemp should be considered the
- reference implementation when adding a new or modifying an
- existing one
-
-*/
-
-File create_temp_file(char *to, const char *dir, const char *prefix,
- int mode __attribute__((unused)),
- myf MyFlags __attribute__((unused)))
-{
- File file= -1;
-#ifdef __WIN__
- TCHAR path_buf[MAX_PATH-14];
-#endif
-
- DBUG_ENTER("create_temp_file");
- DBUG_PRINT("enter", ("dir: %s, prefix: %s", dir, prefix));
-#if defined (__WIN__)
-
- /*
- Use GetTempPath to determine path for temporary files.
- This is because the documentation for GetTempFileName
- has the following to say about this parameter:
- "If this parameter is NULL, the function fails."
- */
- if (!dir)
- {
- if(GetTempPath(sizeof(path_buf), path_buf) > 0)
- dir = path_buf;
- }
- /*
- Use GetTempFileName to generate a unique filename, create
- the file and release it's handle
- - uses up to the first three letters from prefix
- */
- if (GetTempFileName(dir, prefix, 0, to) == 0)
- DBUG_RETURN(-1);
-
- DBUG_PRINT("info", ("name: %s", to));
-
- /*
- Open the file without the "open only if file doesn't already exist"
- since the file has already been created by GetTempFileName
- */
- if ((file= my_open(to, (mode & ~O_EXCL), MyFlags)) < 0)
- {
- /* Open failed, remove the file created by GetTempFileName */
- int tmp= my_errno;
- (void) my_delete(to, MYF(0));
- my_errno= tmp;
- }
-
-#elif defined(HAVE_MKSTEMP)
- {
- char prefix_buff[30];
- uint pfx_len;
- File org_file;
-
- pfx_len= (uint) (strmov(strnmov(prefix_buff,
- prefix ? prefix : "tmp.",
- sizeof(prefix_buff)-7),"XXXXXX") -
- prefix_buff);
- if (!dir && ! (dir =getenv("TMPDIR")))
- dir=P_tmpdir;
- if (strlen(dir)+ pfx_len > FN_REFLEN-2)
- {
- errno=my_errno= ENAMETOOLONG;
- DBUG_RETURN(file);
- }
- strmov(convert_dirname(to,dir,NullS),prefix_buff);
- org_file=mkstemp(to);
- if (mode & O_TEMPORARY)
- (void) my_delete(to, MYF(MY_WME | ME_NOINPUT));
- file=my_register_filename(org_file, to, FILE_BY_MKSTEMP,
- EE_CANTCREATEFILE, MyFlags);
- /* If we didn't manage to register the name, remove the temp file */
- if (org_file >= 0 && file < 0)
- {
- int tmp=my_errno;
- close(org_file);
- (void) my_delete(to, MYF(MY_WME | ME_NOINPUT));
- my_errno=tmp;
- }
- }
-#elif defined(HAVE_TEMPNAM)
- {
- extern char **environ;
-
- char *res,**old_env,*temp_env[1];
- if (dir && !dir[0])
- { /* Change empty string to current dir */
- to[0]= FN_CURLIB;
- to[1]= 0;
- dir=to;
- }
-
- old_env= (char**) environ;
- if (dir)
- { /* Don't use TMPDIR if dir is given */
- environ=(const char**) temp_env;
- temp_env[0]=0;
- }
-
- if ((res=tempnam((char*) dir, (char*) prefix)))
- {
- strmake(to,res,FN_REFLEN-1);
- (*free)(res);
- file=my_create(to,0,
- (int) (O_RDWR | O_BINARY | O_TRUNC | O_EXCL | O_NOFOLLOW |
- O_TEMPORARY | O_SHORT_LIVED),
- MYF(MY_WME));
-
- }
- else
- {
- DBUG_PRINT("error",("Got error: %d from tempnam",errno));
- }
-
- environ=(const char**) old_env;
- }
-#else
-#error No implementation found for create_temp_file
-#endif
- if (file >= 0)
- thread_safe_increment(my_tmp_file_created,&THR_LOCK_open);
- DBUG_RETURN(file);
-}
diff --git a/dep/mysqllite/mysys/mf_unixpath.c b/dep/mysqllite/mysys/mf_unixpath.c
deleted file mode 100644
index ee81aae4584..00000000000
--- a/dep/mysqllite/mysys/mf_unixpath.c
+++ /dev/null
@@ -1,36 +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 <m_string.h>
-
-/**
- Convert filename to unix style filename.
-
- @remark On Windows, converts '\' to '/'.
-
- @param to A pathname.
-*/
-
-void to_unix_path(char *to __attribute__((unused)))
-{
-#if FN_LIBCHAR != '/'
- {
- to--;
- while ((to=strchr(to+1,FN_LIBCHAR)) != 0)
- *to='/';
- }
-#endif
-}
diff --git a/dep/mysqllite/mysys/mf_wcomp.c b/dep/mysqllite/mysys/mf_wcomp.c
deleted file mode 100644
index 4786537d1a5..00000000000
--- a/dep/mysqllite/mysys/mf_wcomp.c
+++ /dev/null
@@ -1,89 +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 */
-
-/* Funktions for comparing with wild-cards */
-
-#include "mysys_priv.h"
-
- /* Test if a string is "comparable" to a wild-card string */
- /* returns 0 if the strings are "comparable" */
-
-char wild_many='*';
-char wild_one='?';
-char wild_prefix=0; /* QQ this can potentially cause a SIGSEGV */
-
-int wild_compare(register const char *str, register const char *wildstr,
- pbool str_is_pattern)
-{
- char cmp;
- DBUG_ENTER("wild_compare");
-
- while (*wildstr)
- {
- while (*wildstr && *wildstr != wild_many && *wildstr != wild_one)
- {
- if (*wildstr == wild_prefix && wildstr[1])
- {
- wildstr++;
- if (str_is_pattern && *str++ != wild_prefix)
- DBUG_RETURN(1);
- }
- if (*wildstr++ != *str++)
- DBUG_RETURN(1);
- }
- if (! *wildstr )
- DBUG_RETURN(*str != 0);
- if (*wildstr++ == wild_one)
- {
- if (! *str || (str_is_pattern && *str == wild_many))
- DBUG_RETURN(1); /* One char; skip */
- if (*str++ == wild_prefix && str_is_pattern && *str)
- str++;
- }
- else
- { /* Found '*' */
- while (str_is_pattern && *str == wild_many)
- str++;
- for (; *wildstr == wild_many || *wildstr == wild_one; wildstr++)
- if (*wildstr == wild_many)
- {
- while (str_is_pattern && *str == wild_many)
- str++;
- }
- else
- {
- if (str_is_pattern && *str == wild_prefix && str[1])
- str+=2;
- else if (! *str++)
- DBUG_RETURN (1);
- }
- if (!*wildstr)
- DBUG_RETURN(0); /* '*' as last char: OK */
- if ((cmp= *wildstr) == wild_prefix && wildstr[1] && !str_is_pattern)
- cmp=wildstr[1];
- for (;;str++)
- {
- while (*str && *str != cmp)
- str++;
- if (!*str)
- DBUG_RETURN (1);
- if (wild_compare(str,wildstr,str_is_pattern) == 0)
- DBUG_RETURN (0);
- }
- /* We will never come here */
- }
- }
- DBUG_RETURN (*str != 0);
-} /* wild_compare */
diff --git a/dep/mysqllite/mysys/mulalloc.c b/dep/mysqllite/mysys/mulalloc.c
deleted file mode 100644
index f4ca3d9f9ab..00000000000
--- a/dep/mysqllite/mysys/mulalloc.c
+++ /dev/null
@@ -1,63 +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 <stdarg.h>
-
-/*
- Malloc many pointers at the same time
- Only ptr1 can be free'd, and doing this will free all
- the memory allocated. ptr2, etc all point inside big allocated
- memory area.
-
- SYNOPSIS
- my_multi_malloc()
- myFlags Flags
- ptr1, length1 Multiple arguments terminated by null ptr
- ptr2, length2 ...
- ...
- NULL
-*/
-
-void* my_multi_malloc(myf myFlags, ...)
-{
- va_list args;
- char **ptr,*start,*res;
- size_t tot_length,length;
- DBUG_ENTER("my_multi_malloc");
-
- va_start(args,myFlags);
- tot_length=0;
- while ((ptr=va_arg(args, char **)))
- {
- length=va_arg(args,uint);
- tot_length+=ALIGN_SIZE(length);
- }
- va_end(args);
-
- if (!(start=(char *) my_malloc(tot_length,myFlags)))
- DBUG_RETURN(0); /* purecov: inspected */
-
- va_start(args,myFlags);
- res=start;
- while ((ptr=va_arg(args, char **)))
- {
- *ptr=res;
- length=va_arg(args,uint);
- res+=ALIGN_SIZE(length);
- }
- va_end(args);
- DBUG_RETURN((void*) start);
-}
diff --git a/dep/mysqllite/mysys/my_access.c b/dep/mysqllite/mysys/my_access.c
deleted file mode 100644
index 210946d50a8..00000000000
--- a/dep/mysqllite/mysys/my_access.c
+++ /dev/null
@@ -1,201 +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 <m_string.h>
-
-#ifdef __WIN__
-
-/*
- Check a file or path for accessability.
-
- SYNOPSIS
- file_access()
- path Path to file
- amode Access method
-
- DESCRIPTION
- This function wraps the normal access method because the access
- available in MSVCRT> +reports that filenames such as LPT1 and
- COM1 are valid (they are but should not be so for us).
-
- RETURN VALUES
- 0 ok
- -1 error (We use -1 as my_access is mapped to access on other platforms)
-*/
-
-int my_access(const char *path, int amode)
-{
- WIN32_FILE_ATTRIBUTE_DATA fileinfo;
- BOOL result;
-
- result= GetFileAttributesEx(path, GetFileExInfoStandard, &fileinfo);
- if (! result ||
- (fileinfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) && (amode & W_OK))
- {
- my_errno= errno= EACCES;
- return -1;
- }
- return 0;
-}
-
-#endif /* __WIN__ */
-
-
-/*
- 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[]=
-{
- "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
-
- SYNOPSIS
- check_if_legal_filename
- path Path to file
-
- RETURN
- 0 ok
- 1 reserved file name
-*/
-
-int check_if_legal_filename(const char *path)
-{
- const char *end;
- const char **reserved_name;
- DBUG_ENTER("check_if_legal_filename");
-
- path+= dirname_length(path); /* To start of filename */
- if (!(end= strchr(path, FN_EXTCHAR)))
- end= strend(path);
- if (path == end || (uint) (end - path) > MAX_RESERVED_NAME_LENGTH)
- DBUG_RETURN(0); /* Simplify inner loop */
-
- for (reserved_name= reserved_names; *reserved_name; reserved_name++)
- {
- const char *reserved= *reserved_name; /* never empty */
- const char *name= path;
-
- do
- {
- if (*reserved != my_toupper(&my_charset_latin1, *name))
- break;
- if (++name == end && !reserved[1])
- DBUG_RETURN(1); /* Found wrong path */
- } while (*++reserved);
- }
- DBUG_RETURN(0);
-}
-
-#endif /* defined(__WIN__) || defined(__EMX__) */
diff --git a/dep/mysqllite/mysys/my_aes.c b/dep/mysqllite/mysys/my_aes.c
deleted file mode 100644
index 575d4702dee..00000000000
--- a/dep/mysqllite/mysys/my_aes.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/* Copyright (C) 2002 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 AES Encryption for MySQL
- Initial version by Peter Zaitsev June 2002
-*/
-
-
-#include <my_global.h>
-#include <m_string.h>
-#include "my_aes.h"
-
-enum encrypt_dir { AES_ENCRYPT, AES_DECRYPT };
-
-#define AES_BLOCK_SIZE 16 /* Block size in bytes */
-
-#define AES_BAD_DATA -1 /* If bad data discovered during decoding */
-
-
-/* The structure for key information */
-typedef struct {
- int nr; /* Number of rounds */
- uint32 rk[4*(AES_MAXNR + 1)]; /* key schedule */
-} KEYINSTANCE;
-
-
-/*
- This is internal function just keeps joint code of Key generation
-
- SYNOPSIS
- my_aes_create_key()
- aes_key Address of Key Instance to be created
- direction Direction (are we encoding or decoding)
- key Key to use for real key creation
- key_length Length of the key
-
- DESCRIPTION
-
- RESULT
- 0 ok
- -1 Error Note: The current impementation never returns this
-*/
-
-static int my_aes_create_key(KEYINSTANCE *aes_key,
- enum encrypt_dir direction, const char *key,
- int key_length)
-{
- uint8 rkey[AES_KEY_LENGTH/8]; /* The real key to be used for encryption */
- uint8 *rkey_end=rkey+AES_KEY_LENGTH/8; /* Real key boundary */
- uint8 *ptr; /* Start of the real key*/
- const char *sptr; /* Start of the working key */
- const char *key_end=key+key_length; /* Working key boundary*/
-
- bzero((char*) rkey,AES_KEY_LENGTH/8); /* Set initial key */
-
- for (ptr= rkey, sptr= key; sptr < key_end; ptr++,sptr++)
- {
- if (ptr == rkey_end)
- ptr= rkey; /* Just loop over tmp_key until we used all key */
- *ptr^= (uint8) *sptr;
- }
-#ifdef AES_USE_KEY_BITS
- /*
- This block is intended to allow more weak encryption if application
- build with libmysqld needs to correspond to export regulations
- It should be never used in normal distribution as does not give
- any speed improvement.
- To get worse security define AES_USE_KEY_BITS to number of bits
- you want key to be. It should be divisible by 8
-
- WARNING: Changing this value results in changing of enryption for
- all key lengths so altering this value will result in impossibility
- to decrypt data encrypted with previous value
- */
-#define AES_USE_KEY_BYTES (AES_USE_KEY_BITS/8)
- /*
- To get weaker key we use first AES_USE_KEY_BYTES bytes of created key
- and cyclically copy them until we created all required key length
- */
- for (ptr= rkey+AES_USE_KEY_BYTES, sptr=rkey ; ptr < rkey_end;
- ptr++,sptr++)
- {
- if (sptr == rkey+AES_USE_KEY_BYTES)
- sptr=rkey;
- *ptr=*sptr;
- }
-#endif
- if (direction == AES_DECRYPT)
- aes_key->nr = rijndaelKeySetupDec(aes_key->rk, rkey, AES_KEY_LENGTH);
- else
- aes_key->nr = rijndaelKeySetupEnc(aes_key->rk, rkey, AES_KEY_LENGTH);
- return 0;
-}
-
-
-/*
- Crypt buffer with AES encryption algorithm.
-
- SYNOPSIS
- my_aes_encrypt()
- source Pointer to data for encryption
- source_length Size of encryption data
- dest Buffer to place encrypted data (must be large enough)
- key Key to be used for encryption
- key_length Length of the key. Will handle keys of any length
-
- RETURN
- >= 0 Size of encrypted data
- < 0 Error
-*/
-
-int my_aes_encrypt(const char* source, int source_length, char* dest,
- const char* key, int key_length)
-{
- KEYINSTANCE aes_key;
- uint8 block[AES_BLOCK_SIZE]; /* 128 bit block used for padding */
- int rc; /* result codes */
- int num_blocks; /* number of complete blocks */
- char pad_len; /* pad size for the last block */
- int i;
-
- if ((rc= my_aes_create_key(&aes_key,AES_ENCRYPT,key,key_length)))
- return rc;
-
- num_blocks = source_length/AES_BLOCK_SIZE;
-
- for (i = num_blocks; i > 0; i--) /* Encode complete blocks */
- {
- rijndaelEncrypt(aes_key.rk, aes_key.nr, (const uint8*) source,
- (uint8*) dest);
- source+= AES_BLOCK_SIZE;
- dest+= AES_BLOCK_SIZE;
- }
-
- /* Encode the rest. We always have incomplete block */
- pad_len = AES_BLOCK_SIZE - (source_length - AES_BLOCK_SIZE*num_blocks);
- memcpy(block, source, 16 - pad_len);
- bfill(block + AES_BLOCK_SIZE - pad_len, pad_len, pad_len);
- rijndaelEncrypt(aes_key.rk, aes_key.nr, block, (uint8*) dest);
- return AES_BLOCK_SIZE*(num_blocks + 1);
-}
-
-
-/*
- DeCrypt buffer with AES encryption algorithm.
-
- SYNOPSIS
- my_aes_decrypt()
- source Pointer to data for decryption
- source_length Size of encrypted data
- dest Buffer to place decrypted data (must be large enough)
- key Key to be used for decryption
- key_length Length of the key. Will handle keys of any length
-
- RETURN
- >= 0 Size of encrypted data
- < 0 Error
-*/
-
-int my_aes_decrypt(const char *source, int source_length, char *dest,
- const char *key, int key_length)
-{
- KEYINSTANCE aes_key;
- uint8 block[AES_BLOCK_SIZE]; /* 128 bit block used for padding */
- int rc; /* Result codes */
- int num_blocks; /* Number of complete blocks */
- uint pad_len; /* Pad size for the last block */
- int i;
-
- if ((rc=my_aes_create_key(&aes_key,AES_DECRYPT,key,key_length)))
- return rc;
-
- num_blocks = source_length/AES_BLOCK_SIZE;
-
- if ((source_length != num_blocks*AES_BLOCK_SIZE) || num_blocks ==0 )
- return AES_BAD_DATA; /* Input size has to be even and at least one block */
-
- for (i = num_blocks-1; i > 0; i--) /* Decode all but last blocks */
- {
- rijndaelDecrypt(aes_key.rk, aes_key.nr, (const uint8*) source,
- (uint8*) dest);
- source+= AES_BLOCK_SIZE;
- dest+= AES_BLOCK_SIZE;
- }
-
- rijndaelDecrypt(aes_key.rk, aes_key.nr, (const uint8*) source, block);
- /* Use last char in the block as size */
- pad_len = (uint) (uchar) block[AES_BLOCK_SIZE-1];
-
- if (pad_len > AES_BLOCK_SIZE)
- return AES_BAD_DATA;
- /* We could also check whole padding but we do not really need this */
-
- memcpy(dest, block, AES_BLOCK_SIZE - pad_len);
- return AES_BLOCK_SIZE*num_blocks - pad_len;
-}
-
-
-/*
- Get size of buffer which will be large enough for encrypted data
-
- SYNOPSIS
- my_aes_get_size()
- source_length Length of data to be encrypted
-
- RETURN
- Size of buffer required to store encrypted data
-*/
-
-int my_aes_get_size(int source_length)
-{
- return AES_BLOCK_SIZE*(source_length/AES_BLOCK_SIZE)+AES_BLOCK_SIZE;
-}
diff --git a/dep/mysqllite/mysys/my_alarm.c b/dep/mysqllite/mysys/my_alarm.c
deleted file mode 100644
index d6a0da1bd13..00000000000
--- a/dep/mysqllite/mysys/my_alarm.c
+++ /dev/null
@@ -1,32 +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 */
-
-/* Function to set a varible when we got a alarm */
-/* Used by my_lock samt functions in m_alarm.h */
-
-
-#include "mysys_priv.h"
-#include "my_alarm.h"
-
-#ifdef HAVE_ALARM
-
- /* ARGSUSED */
-sig_handler my_set_alarm_variable(int signo __attribute__((unused)))
-{
- my_have_got_alarm=1; /* Tell program that time expired */
- return;
-}
-
-#endif /* HAVE_ALARM */
diff --git a/dep/mysqllite/mysys/my_alloc.c b/dep/mysqllite/mysys/my_alloc.c
deleted file mode 100644
index 903826dd975..00000000000
--- a/dep/mysqllite/mysys/my_alloc.c
+++ /dev/null
@@ -1,436 +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 */
-
-/* Routines to handle mallocing of results which will be freed the same time */
-
-#include <my_global.h>
-#include <my_sys.h>
-#include <m_string.h>
-#undef EXTRA_DEBUG
-#define EXTRA_DEBUG
-
-
-/*
- Initialize memory root
-
- SYNOPSIS
- init_alloc_root()
- mem_root - memory root to initialize
- block_size - size of chunks (blocks) used for memory allocation
- (It is external size of chunk i.e. it should include
- memory required for internal structures, thus it
- should be no less than ALLOC_ROOT_MIN_BLOCK_SIZE)
- pre_alloc_size - if non-0, then size of block that should be
- pre-allocated during memory root initialization.
-
- DESCRIPTION
- This function prepares memory root for further use, sets initial size of
- chunk for memory allocation and pre-allocates first block if specified.
- Altough error can happen during execution of this function if
- pre_alloc_size is non-0 it won't be reported. Instead it will be
- reported as error in first alloc_root() on this memory root.
-*/
-
-void init_alloc_root(MEM_ROOT *mem_root, size_t block_size,
- size_t pre_alloc_size __attribute__((unused)))
-{
- DBUG_ENTER("init_alloc_root");
- DBUG_PRINT("enter",("root: 0x%lx", (long) mem_root));
-
- mem_root->free= mem_root->used= mem_root->pre_alloc= 0;
- mem_root->min_malloc= 32;
- mem_root->block_size= block_size - ALLOC_ROOT_MIN_BLOCK_SIZE;
- mem_root->error_handler= 0;
- mem_root->block_num= 4; /* We shift this with >>2 */
- mem_root->first_block_usage= 0;
-
-#if !(defined(HAVE_purify) && defined(EXTRA_DEBUG))
- if (pre_alloc_size)
- {
- if ((mem_root->free= mem_root->pre_alloc=
- (USED_MEM*) my_malloc(pre_alloc_size+ ALIGN_SIZE(sizeof(USED_MEM)),
- MYF(0))))
- {
- mem_root->free->size= pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM));
- mem_root->free->left= pre_alloc_size;
- mem_root->free->next= 0;
- }
- }
-#endif
- DBUG_VOID_RETURN;
-}
-
-
-/*
- SYNOPSIS
- reset_root_defaults()
- mem_root memory root to change defaults of
- block_size new value of block size. Must be greater or equal
- than ALLOC_ROOT_MIN_BLOCK_SIZE (this value is about
- 68 bytes and depends on platform and compilation flags)
- pre_alloc_size new size of preallocated block. If not zero,
- must be equal to or greater than block size,
- otherwise means 'no prealloc'.
- DESCRIPTION
- Function aligns and assigns new value to block size; then it tries to
- reuse one of existing blocks as prealloc block, or malloc new one of
- requested size. If no blocks can be reused, all unused blocks are freed
- before allocation.
-*/
-
-void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size,
- size_t pre_alloc_size __attribute__((unused)))
-{
- DBUG_ASSERT(alloc_root_inited(mem_root));
-
- mem_root->block_size= block_size - ALLOC_ROOT_MIN_BLOCK_SIZE;
-#if !(defined(HAVE_purify) && defined(EXTRA_DEBUG))
- if (pre_alloc_size)
- {
- size_t size= pre_alloc_size + ALIGN_SIZE(sizeof(USED_MEM));
- if (!mem_root->pre_alloc || mem_root->pre_alloc->size != size)
- {
- USED_MEM *mem, **prev= &mem_root->free;
- /*
- Free unused blocks, so that consequent calls
- to reset_root_defaults won't eat away memory.
- */
- while (*prev)
- {
- mem= *prev;
- if (mem->size == size)
- {
- /* We found a suitable block, no need to do anything else */
- mem_root->pre_alloc= mem;
- return;
- }
- if (mem->left + ALIGN_SIZE(sizeof(USED_MEM)) == mem->size)
- {
- /* remove block from the list and free it */
- *prev= mem->next;
- my_free(mem);
- }
- else
- prev= &mem->next;
- }
- /* Allocate new prealloc block and add it to the end of free list */
- if ((mem= (USED_MEM *) my_malloc(size, MYF(0))))
- {
- mem->size= size;
- mem->left= pre_alloc_size;
- mem->next= *prev;
- *prev= mem_root->pre_alloc= mem;
- }
- else
- {
- mem_root->pre_alloc= 0;
- }
- }
- }
- else
-#endif
- mem_root->pre_alloc= 0;
-}
-
-
-void *alloc_root(MEM_ROOT *mem_root, size_t length)
-{
-#if defined(HAVE_purify) && defined(EXTRA_DEBUG)
- reg1 USED_MEM *next;
- DBUG_ENTER("alloc_root");
- DBUG_PRINT("enter",("root: 0x%lx", (long) mem_root));
-
- DBUG_ASSERT(alloc_root_inited(mem_root));
-
- DBUG_EXECUTE_IF("simulate_out_of_memory",
- {
- if (mem_root->error_handler)
- (*mem_root->error_handler)();
- DBUG_SET("-d,simulate_out_of_memory");
- DBUG_RETURN((void*) 0); /* purecov: inspected */
- });
-
- length+=ALIGN_SIZE(sizeof(USED_MEM));
- if (!(next = (USED_MEM*) my_malloc(length,MYF(MY_WME | ME_FATALERROR))))
- {
- if (mem_root->error_handler)
- (*mem_root->error_handler)();
- DBUG_RETURN((uchar*) 0); /* purecov: inspected */
- }
- next->next= mem_root->used;
- next->size= length;
- mem_root->used= next;
- DBUG_PRINT("exit",("ptr: 0x%lx", (long) (((char*) next)+
- ALIGN_SIZE(sizeof(USED_MEM)))));
- DBUG_RETURN((uchar*) (((char*) next)+ALIGN_SIZE(sizeof(USED_MEM))));
-#else
- size_t get_size, block_size;
- uchar* point;
- reg1 USED_MEM *next= 0;
- reg2 USED_MEM **prev;
- DBUG_ENTER("alloc_root");
- DBUG_PRINT("enter",("root: 0x%lx", (long) mem_root));
- DBUG_ASSERT(alloc_root_inited(mem_root));
-
- DBUG_EXECUTE_IF("simulate_out_of_memory",
- {
- /* Avoid reusing an already allocated block */
- if (mem_root->error_handler)
- (*mem_root->error_handler)();
- DBUG_SET("-d,simulate_out_of_memory");
- DBUG_RETURN((void*) 0); /* purecov: inspected */
- });
- length= ALIGN_SIZE(length);
- if ((*(prev= &mem_root->free)) != NULL)
- {
- if ((*prev)->left < length &&
- mem_root->first_block_usage++ >= ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP &&
- (*prev)->left < ALLOC_MAX_BLOCK_TO_DROP)
- {
- next= *prev;
- *prev= next->next; /* Remove block from list */
- next->next= mem_root->used;
- mem_root->used= next;
- mem_root->first_block_usage= 0;
- }
- for (next= *prev ; next && next->left < length ; next= next->next)
- prev= &next->next;
- }
- if (! next)
- { /* Time to alloc new block */
- block_size= mem_root->block_size * (mem_root->block_num >> 2);
- get_size= length+ALIGN_SIZE(sizeof(USED_MEM));
- get_size= max(get_size, block_size);
-
- if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME | ME_FATALERROR))))
- {
- if (mem_root->error_handler)
- (*mem_root->error_handler)();
- DBUG_RETURN((void*) 0); /* purecov: inspected */
- }
- mem_root->block_num++;
- next->next= *prev;
- next->size= get_size;
- next->left= get_size-ALIGN_SIZE(sizeof(USED_MEM));
- *prev=next;
- }
-
- point= (uchar*) ((char*) next+ (next->size-next->left));
- /*TODO: next part may be unneded due to mem_root->first_block_usage counter*/
- if ((next->left-= length) < mem_root->min_malloc)
- { /* Full block */
- *prev= next->next; /* Remove block from list */
- next->next= mem_root->used;
- mem_root->used= next;
- mem_root->first_block_usage= 0;
- }
- DBUG_PRINT("exit",("ptr: 0x%lx", (ulong) point));
- DBUG_RETURN((void*) point);
-#endif
-}
-
-
-/*
- Allocate many pointers at the same time.
-
- DESCRIPTION
- ptr1, ptr2, etc all point into big allocated memory area.
-
- SYNOPSIS
- multi_alloc_root()
- root Memory root
- ptr1, length1 Multiple arguments terminated by a NULL pointer
- ptr2, length2 ...
- ...
- NULL
-
- RETURN VALUE
- A pointer to the beginning of the allocated memory block
- in case of success or NULL if out of memory.
-*/
-
-void *multi_alloc_root(MEM_ROOT *root, ...)
-{
- va_list args;
- char **ptr, *start, *res;
- size_t tot_length, length;
- DBUG_ENTER("multi_alloc_root");
-
- va_start(args, root);
- tot_length= 0;
- while ((ptr= va_arg(args, char **)))
- {
- length= va_arg(args, uint);
- tot_length+= ALIGN_SIZE(length);
- }
- va_end(args);
-
- if (!(start= (char*) alloc_root(root, tot_length)))
- DBUG_RETURN(0); /* purecov: inspected */
-
- va_start(args, root);
- res= start;
- while ((ptr= va_arg(args, char **)))
- {
- *ptr= res;
- length= va_arg(args, uint);
- res+= ALIGN_SIZE(length);
- }
- va_end(args);
- DBUG_RETURN((void*) start);
-}
-
-#define TRASH_MEM(X) TRASH(((char*)(X) + ((X)->size-(X)->left)), (X)->left)
-
-/* Mark all data in blocks free for reusage */
-
-static inline void mark_blocks_free(MEM_ROOT* root)
-{
- reg1 USED_MEM *next;
- reg2 USED_MEM **last;
-
- /* iterate through (partially) free blocks, mark them free */
- last= &root->free;
- for (next= root->free; next; next= *(last= &next->next))
- {
- next->left= next->size - ALIGN_SIZE(sizeof(USED_MEM));
- TRASH_MEM(next);
- }
-
- /* Combine the free and the used list */
- *last= next=root->used;
-
- /* now go through the used blocks and mark them free */
- for (; next; next= next->next)
- {
- next->left= next->size - ALIGN_SIZE(sizeof(USED_MEM));
- TRASH_MEM(next);
- }
-
- /* Now everything is set; Indicate that nothing is used anymore */
- root->used= 0;
- root->first_block_usage= 0;
-}
-
-
-/*
- Deallocate everything used by alloc_root or just move
- used blocks to free list if called with MY_USED_TO_FREE
-
- SYNOPSIS
- free_root()
- root Memory root
- MyFlags Flags for what should be freed:
-
- MY_MARK_BLOCKS_FREED Don't free blocks, just mark them free
- MY_KEEP_PREALLOC If this is not set, then free also the
- preallocated block
-
- NOTES
- One can call this function either with root block initialised with
- init_alloc_root() or with a bzero()-ed block.
- It's also safe to call this multiple times with the same mem_root.
-*/
-
-void free_root(MEM_ROOT *root, myf MyFlags)
-{
- reg1 USED_MEM *next,*old;
- DBUG_ENTER("free_root");
- DBUG_PRINT("enter",("root: 0x%lx flags: %u", (long) root, (uint) MyFlags));
-
- if (MyFlags & MY_MARK_BLOCKS_FREE)
- {
- mark_blocks_free(root);
- DBUG_VOID_RETURN;
- }
- if (!(MyFlags & MY_KEEP_PREALLOC))
- root->pre_alloc=0;
-
- for (next=root->used; next ;)
- {
- old=next; next= next->next ;
- if (old != root->pre_alloc)
- my_free(old);
- }
- for (next=root->free ; next ;)
- {
- old=next; next= next->next;
- if (old != root->pre_alloc)
- my_free(old);
- }
- root->used=root->free=0;
- if (root->pre_alloc)
- {
- root->free=root->pre_alloc;
- root->free->left=root->pre_alloc->size-ALIGN_SIZE(sizeof(USED_MEM));
- TRASH_MEM(root->pre_alloc);
- root->free->next=0;
- }
- root->block_num= 4;
- root->first_block_usage= 0;
- DBUG_VOID_RETURN;
-}
-
-/*
- Find block that contains an object and set the pre_alloc to it
-*/
-
-void set_prealloc_root(MEM_ROOT *root, char *ptr)
-{
- USED_MEM *next;
- for (next=root->used; next ; next=next->next)
- {
- if ((char*) next <= ptr && (char*) next + next->size > ptr)
- {
- root->pre_alloc=next;
- return;
- }
- }
- for (next=root->free ; next ; next=next->next)
- {
- if ((char*) next <= ptr && (char*) next + next->size > ptr)
- {
- root->pre_alloc=next;
- return;
- }
- }
-}
-
-
-char *strdup_root(MEM_ROOT *root, const char *str)
-{
- return strmake_root(root, str, strlen(str));
-}
-
-
-char *strmake_root(MEM_ROOT *root, const char *str, size_t len)
-{
- char *pos;
- if ((pos=alloc_root(root,len+1)))
- {
- memcpy(pos,str,len);
- pos[len]=0;
- }
- return pos;
-}
-
-
-void *memdup_root(MEM_ROOT *root, const void *str, size_t len)
-{
- char *pos;
- if ((pos=alloc_root(root,len)))
- memcpy(pos,str,len);
- return pos;
-}
diff --git a/dep/mysqllite/mysys/my_atomic.c b/dep/mysqllite/mysys/my_atomic.c
deleted file mode 100644
index 7cbe15cfb74..00000000000
--- a/dep/mysqllite/mysys/my_atomic.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Copyright (C) 2006 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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_sys.h>
-
-#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()
-{
- compile_time_assert(sizeof(intptr) == sizeof(void *));
- /* currently the only thing worth checking is SMP/UP issue */
-#ifdef MY_ATOMIC_MODE_DUMMY
- return my_getncpus() == 1 ? MY_ATOMIC_OK : MY_ATOMIC_NOT_1CPU;
-#else
- return MY_ATOMIC_OK;
-#endif
-}
-
-#ifdef SAFE_MUTEX
-#undef pthread_mutex_init
-#undef pthread_mutex_destroy
-#undef pthread_mutex_lock
-#undef pthread_mutex_unlock
-
-void plain_pthread_mutex_init(safe_mutex_t *m)
-{
- pthread_mutex_init(& m->mutex, NULL);
-}
-
-void plain_pthread_mutex_destroy(safe_mutex_t *m)
-{
- pthread_mutex_destroy(& m->mutex);
-}
-
-void plain_pthread_mutex_lock(safe_mutex_t *m)
-{
- pthread_mutex_lock(& m->mutex);
-}
-
-void plain_pthread_mutex_unlock(safe_mutex_t *m)
-{
- pthread_mutex_unlock(& m->mutex);
-}
-
-#endif
-
-
diff --git a/dep/mysqllite/mysys/my_bit.c b/dep/mysqllite/mysys/my_bit.c
deleted file mode 100644
index f072f243765..00000000000
--- a/dep/mysqllite/mysys/my_bit.c
+++ /dev/null
@@ -1,64 +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 <my_global.h>
-
-#include <my_bit.h>
-
-const char _my_bits_nbits[256] = {
- 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
- 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
- 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
- 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
- 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
- 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
- 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
- 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
- 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
- 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
-};
-
-/*
- perl -e 'print map{", 0x".unpack H2,pack B8,unpack b8,chr$_}(0..255)'
-*/
-const uchar _my_bits_reverse_table[256]={
-0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30,
-0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98,
-0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64,
-0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 0x0C, 0x8C, 0x4C, 0xCC,
-0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, 0x02,
-0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2,
-0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A,
-0xDA, 0x3A, 0xBA, 0x7A, 0xFA, 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
-0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, 0x4E, 0xCE, 0x2E,
-0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81,
-0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71,
-0xF1, 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9,
-0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15,
-0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD,
-0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, 0x03, 0x83, 0x43,
-0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
-0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B,
-0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97,
-0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F,
-0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
-};
-
diff --git a/dep/mysqllite/mysys/my_bitmap.c b/dep/mysqllite/mysys/my_bitmap.c
deleted file mode 100644
index dc15014121b..00000000000
--- a/dep/mysqllite/mysys/my_bitmap.c
+++ /dev/null
@@ -1,932 +0,0 @@
-/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 */
-
-/*
- Handling of uchar arrays as large bitmaps.
-
- API limitations (or, rather asserted safety assumptions,
- to encourage correct programming)
-
- * 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_*
-
- 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>
-#include <my_bit.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)))
-{
- if (map->mutex)
- mysql_mutex_lock(map->mutex);
-}
-
-static inline void bitmap_unlock(MY_BITMAP *map __attribute__((unused)))
-{
- if (map->mutex)
- mysql_mutex_unlock(map->mutex);
-}
-
-
-my_bool bitmap_init(MY_BITMAP *map, my_bitmap_map *buf, uint n_bits,
- my_bool thread_safe __attribute__((unused)))
-{
- DBUG_ENTER("bitmap_init");
- if (!buf)
- {
- uint size_in_bytes= bitmap_buffer_size(n_bits);
- uint extra= 0;
-
- if (thread_safe)
- {
- size_in_bytes= ALIGN_SIZE(size_in_bytes);
- extra= sizeof(mysql_mutex_t);
- }
- map->mutex= 0;
-
- if (!(buf= (my_bitmap_map*) my_malloc(size_in_bytes+extra, MYF(MY_WME))))
- DBUG_RETURN(1);
-
- if (thread_safe)
- {
- map->mutex= (mysql_mutex_t *) ((char*) buf + size_in_bytes);
- mysql_mutex_init(key_BITMAP_mutex, map->mutex, MY_MUTEX_INIT_FAST);
- }
-
- }
-
- else
- {
- DBUG_ASSERT(thread_safe == 0);
- }
-
-
- map->bitmap= buf;
- map->n_bits= n_bits;
- create_last_word_mask(map);
- bitmap_clear_all(map);
- DBUG_RETURN(0);
-}
-
-
-void bitmap_free(MY_BITMAP *map)
-{
- DBUG_ENTER("bitmap_free");
- if (map->bitmap)
- {
- if (map->mutex)
- mysql_mutex_destroy(map->mutex);
-
- my_free(map->bitmap);
- map->bitmap=0;
- }
- DBUG_VOID_RETURN;
-}
-
-
-/*
- test if bit already set and set it if it was not (thread unsafe method)
-
- SYNOPSIS
- bitmap_fast_test_and_set()
- MAP bit map struct
- BIT bit number
-
- RETURN
- 0 bit was not set
- !=0 bit was set
-*/
-
-my_bool bitmap_fast_test_and_set(MY_BITMAP *map, uint bitmap_bit)
-{
- uchar *value= ((uchar*) map->bitmap) + (bitmap_bit / 8);
- uchar bit= 1 << ((bitmap_bit) & 7);
- uchar res= (*value) & bit;
- *value|= bit;
- return res;
-}
-
-
-/*
- test if bit already set and set it if it was not (thread safe method)
-
- SYNOPSIS
- bitmap_fast_test_and_set()
- map bit map struct
- bitmap_bit bit number
-
- RETURN
- 0 bit was not set
- !=0 bit was set
-*/
-
-my_bool bitmap_test_and_set(MY_BITMAP *map, uint bitmap_bit)
-{
- my_bool res;
- 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;
-}
-
-/*
- test if bit already set and clear it if it was set(thread unsafe method)
-
- SYNOPSIS
- bitmap_fast_test_and_set()
- MAP bit map struct
- BIT bit number
-
- RETURN
- 0 bit was not set
- !=0 bit was set
-*/
-
-my_bool bitmap_fast_test_and_clear(MY_BITMAP *map, uint bitmap_bit)
-{
- uchar *byte= (uchar*) map->bitmap + (bitmap_bit / 8);
- uchar bit= 1 << ((bitmap_bit) & 7);
- uchar res= (*byte) & bit;
- *byte&= ~bit;
- return res;
-}
-
-
-my_bool bitmap_test_and_clear(MY_BITMAP *map, uint bitmap_bit)
-{
- my_bool res;
- DBUG_ASSERT(map->bitmap && bitmap_bit < map->n_bits);
- bitmap_lock(map);
- res= bitmap_fast_test_and_clear(map, bitmap_bit);
- bitmap_unlock(map);
- return res;
-}
-
-
-uint bitmap_set_next(MY_BITMAP *map)
-{
- 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_prefix(MY_BITMAP *map, uint prefix_size)
-{
- 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 & 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);
-
- while (m < end_prefix)
- if (*m++ != 0xff)
- 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;
-ret:
- return res;
-}
-
-
-my_bool bitmap_is_set_all(const MY_BITMAP *map)
-{
- 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_clear_all(const MY_BITMAP *map)
-{
- 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)
-{
- my_bitmap_map *m1= map1->bitmap, *m2= map2->bitmap, *end;
-
- DBUG_ASSERT(map1->bitmap && map2->bitmap &&
- map1->n_bits==map2->n_bits);
-
- 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 0;
- }
- return 1;
-}
-
-/* True if bitmaps has any common bits */
-
-my_bool bitmap_is_overlapping(const MY_BITMAP *map1, const MY_BITMAP *map2)
-{
- my_bitmap_map *m1= map1->bitmap, *m2= map2->bitmap, *end;
-
- DBUG_ASSERT(map1->bitmap && map2->bitmap &&
- map1->n_bits==map2->n_bits);
-
- 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)
-{
- 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);
-
- end= to+min(len,len2);
- *map2->last_word_ptr&= ~map2->last_word_mask; /*Clear last bits in map2*/
- while (to < end)
- *to++ &= *from++;
-
- if (len2 < len)
- {
- end+=len-len2;
- while (to < end)
- *to++=0;
- }
-}
-
-
-/*
- Set/clear all bits above a bit.
-
- SYNOPSIS
- bitmap_set_above()
- map RETURN The bitmap to change.
- from_byte The bitmap buffer byte offset to start with.
- use_bit The bit value (1/0) to use for all upper bits.
-
- NOTE
- You can only set/clear full bytes.
- The function is meant for the situation that you copy a smaller bitmap
- to a bigger bitmap. Bitmap lengths are always multiple of eigth (the
- size of a byte). Using 'from_byte' saves multiplication and division
- by eight during parameter passing.
-
- RETURN
- void
-*/
-
-void bitmap_set_above(MY_BITMAP *map, uint from_byte, uint use_bit)
-{
- uchar use_byte= use_bit ? 0xff : 0;
- uchar *to= (uchar *)map->bitmap + from_byte;
- uchar *end= (uchar *)map->bitmap + (map->n_bits+7)/8;
-
- while (to < end)
- *to++= use_byte;
-}
-
-
-void bitmap_subtract(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_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->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;
- }
- }
- }
- }
- }
- 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;
- }
- }
- }
- }
- }
- return MY_BIT_NONE;
-}
-
-
-uint bitmap_lock_set_next(MY_BITMAP *map)
-{
- uint bit_found;
- bitmap_lock(map);
- bit_found= bitmap_set_next(map);
- bitmap_unlock(map);
- return bit_found;
-}
-
-
-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);
-}
-
-#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)
-{
- 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;
-}
-
-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++)
- {
- 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);
- }
- 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/dep/mysqllite/mysys/my_chsize.c b/dep/mysqllite/mysys/my_chsize.c
deleted file mode 100644
index b9013811b34..00000000000
--- a/dep/mysqllite/mysys/my_chsize.c
+++ /dev/null
@@ -1,107 +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"
-#include "m_string.h"
-
-/*
- Change size of file.
-
- SYNOPSIS
- my_chsize()
- fd File descriptor
- new_length New file size
- filler If we don't have truncate, fill up all bytes after
- new_length with this character
- MyFlags Flags
-
- DESCRIPTION
- my_chsize() truncates file if shorter else fill with the filler character.
- The function also changes the file pointer. Usually it points to the end
- of the file after execution.
-
- RETURN VALUE
- 0 Ok
- 1 Error
-*/
-int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
-{
- my_off_t oldsize;
- uchar buff[IO_SIZE];
- DBUG_ENTER("my_chsize");
- DBUG_PRINT("my",("fd: %d length: %lu MyFlags: %d",fd,(ulong) newlength,
- MyFlags));
-
- if ((oldsize= my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE))) == newlength)
- DBUG_RETURN(0);
-
- DBUG_PRINT("info",("old_size: %ld", (ulong) oldsize));
-
- if (oldsize > newlength)
- {
-#ifdef _WIN32
- if (my_win_chsize(fd, newlength))
- {
- my_errno= errno;
- goto err;
- }
- DBUG_RETURN(0);
-#elif defined(HAVE_FTRUNCATE)
- if (ftruncate(fd, (off_t) newlength))
- {
- my_errno= errno;
- goto err;
- }
- DBUG_RETURN(0);
-#elif defined(HAVE_CHSIZE)
- if (chsize(fd, (off_t) newlength))
- {
- my_errno=errno;
- goto err;
- }
- DBUG_RETURN(0);
-#else
- /*
- Fill space between requested length and true length with 'filler'
- We should never come here on any modern machine
- */
- if (my_seek(fd, newlength, MY_SEEK_SET, MYF(MY_WME+MY_FAE))
- == MY_FILEPOS_ERROR)
- {
- goto err;
- }
- swap_variables(my_off_t, newlength, oldsize);
-#endif
- }
-
- /* Full file with 'filler' until it's as big as requested */
- bfill(buff, IO_SIZE, filler);
- while (newlength-oldsize > IO_SIZE)
- {
- if (my_write(fd, buff, IO_SIZE, MYF(MY_NABP)))
- goto err;
- oldsize+= IO_SIZE;
- }
- if (my_write(fd,buff,(size_t) (newlength-oldsize), MYF(MY_NABP)))
- goto err;
- DBUG_RETURN(0);
-
-err:
- DBUG_PRINT("error", ("errno: %d", errno));
- if (MyFlags & MY_WME)
- my_error(EE_CANT_CHSIZE, MYF(ME_BELL+ME_WAITTANG), my_errno);
- DBUG_RETURN(1);
-} /* my_chsize */
diff --git a/dep/mysqllite/mysys/my_compress.c b/dep/mysqllite/mysys/my_compress.c
deleted file mode 100644
index 360390d376a..00000000000
--- a/dep/mysqllite/mysys/my_compress.c
+++ /dev/null
@@ -1,264 +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 */
-
-/* Written by Sinisa Milivojevic <sinisa@mysql.com> */
-
-#include <my_global.h>
-#ifdef HAVE_COMPRESS
-#include <my_sys.h>
-#ifndef SCO
-#include <m_string.h>
-#endif
-#include <zlib.h>
-
-/*
- This replaces the packet with a compressed packet
-
- SYNOPSIS
- my_compress()
- packet Data to compress. This is is replaced with the compressed data.
- len Length of data to compress at 'packet'
- complen out: 0 if packet was not compressed
-
- RETURN
- 1 error. 'len' is not changed'
- 0 ok. In this case 'len' contains the size of the compressed packet
-*/
-
-my_bool my_compress(uchar *packet, size_t *len, size_t *complen)
-{
- DBUG_ENTER("my_compress");
- if (*len < MIN_COMPRESS_LENGTH)
- {
- *complen=0;
- DBUG_PRINT("note",("Packet too short: Not compressed"));
- }
- else
- {
- uchar *compbuf=my_compress_alloc(packet,len,complen);
- if (!compbuf)
- DBUG_RETURN(*complen ? 0 : 1);
- memcpy(packet,compbuf,*len);
- my_free(compbuf);
- }
- DBUG_RETURN(0);
-}
-
-
-uchar *my_compress_alloc(const uchar *packet, size_t *len, size_t *complen)
-{
- uchar *compbuf;
- uLongf tmp_complen;
- int res;
- *complen= *len * 120 / 100 + 12;
-
- if (!(compbuf= (uchar *) my_malloc(*complen, MYF(MY_WME))))
- return 0; /* Not enough memory */
-
- tmp_complen= (uint) *complen;
- res= compress((Bytef*) compbuf, &tmp_complen, (Bytef*) packet, (uLong) *len);
- *complen= tmp_complen;
-
- if (res != Z_OK)
- {
- my_free(compbuf);
- return 0;
- }
-
- if (*complen >= *len)
- {
- *complen= 0;
- my_free(compbuf);
- DBUG_PRINT("note",("Packet got longer on compression; Not compressed"));
- return 0;
- }
- /* Store length of compressed packet in *len */
- swap_variables(size_t, *len, *complen);
- return compbuf;
-}
-
-
-/*
- Uncompress packet
-
- SYNOPSIS
- my_uncompress()
- packet Compressed data. This is is replaced with the orignal data.
- len Length of compressed data
- complen Length of the packet buffer (must be enough for the original
- data)
-
- RETURN
- 1 error
- 0 ok. In this case 'complen' contains the updated size of the
- real data.
-*/
-
-my_bool my_uncompress(uchar *packet, size_t len, size_t *complen)
-{
- uLongf tmp_complen;
- DBUG_ENTER("my_uncompress");
-
- if (*complen) /* If compressed */
- {
- uchar *compbuf= (uchar *) my_malloc(*complen,MYF(MY_WME));
- int error;
- if (!compbuf)
- DBUG_RETURN(1); /* Not enough memory */
-
- tmp_complen= (uint) *complen;
- error= uncompress((Bytef*) compbuf, &tmp_complen, (Bytef*) packet,
- (uLong) len);
- *complen= tmp_complen;
- if (error != Z_OK)
- { /* Probably wrong packet */
- DBUG_PRINT("error",("Can't uncompress packet, error: %d",error));
- my_free(compbuf);
- DBUG_RETURN(1);
- }
- memcpy(packet, compbuf, *complen);
- my_free(compbuf);
- }
- else
- *complen= len;
- DBUG_RETURN(0);
-}
-
-/*
- Internal representation of the frm blob is:
-
- ver 4 bytes
- orglen 4 bytes
- complen 4 bytes
-*/
-
-#define BLOB_HEADER 12
-
-
-/*
- 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
-
- NOTES
- data is replaced with compressed content
-
- RETURN VALUES
- 0 Success
- >0 Failure
-*/
-
-int packfrm(uchar *data, size_t len,
- uchar **pack_data, size_t *pack_len)
-{
- int error;
- size_t org_len, comp_len, blob_len;
- uchar *blob;
- DBUG_ENTER("packfrm");
- DBUG_PRINT("enter", ("data: 0x%lx len: %lu", (long) data, (ulong) len));
-
- error= 1;
- org_len= len;
- if (my_compress((uchar*)data, &org_len, &comp_len))
- goto err;
-
- DBUG_PRINT("info", ("org_len: %lu comp_len: %lu", (ulong) org_len,
- (ulong) comp_len));
- DBUG_DUMP("compressed", data, org_len);
-
- error= 2;
- blob_len= BLOB_HEADER + org_len;
- if (!(blob= (uchar*) my_malloc(blob_len,MYF(MY_WME))))
- goto err;
-
- /* Store compressed blob in machine independent format */
- int4store(blob, 1);
- int4store(blob+4, (uint32) len);
- int4store(blob+8, (uint32) org_len); /* compressed length */
-
- /* Copy frm data into blob, already in machine independent format */
- memcpy(blob+BLOB_HEADER, data, org_len);
-
- *pack_data= blob;
- *pack_len= blob_len;
- error= 0;
-
- DBUG_PRINT("exit", ("pack_data: 0x%lx pack_len: %lu",
- (long) *pack_data, (ulong) *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(uchar **unpack_data, size_t *unpack_len,
- const uchar *pack_data)
-{
- uchar *data;
- size_t complen, orglen;
- ulong ver;
- DBUG_ENTER("unpackfrm");
- DBUG_PRINT("enter", ("pack_data: 0x%lx", (long) pack_data));
-
- ver= uint4korr(pack_data);
- orglen= uint4korr(pack_data+4);
- complen= uint4korr(pack_data+8);
-
- DBUG_PRINT("blob",("ver: %lu complen: %lu orglen: %lu",
- ver, (ulong) complen, (ulong) orglen));
- DBUG_DUMP("blob->data", pack_data + BLOB_HEADER, complen);
-
- if (ver != 1)
- DBUG_RETURN(1);
- if (!(data= my_malloc(max(orglen, complen), MYF(MY_WME))))
- DBUG_RETURN(2);
- memcpy(data, pack_data + BLOB_HEADER, complen);
-
- if (my_uncompress(data, complen, &orglen))
- {
- my_free(data);
- DBUG_RETURN(3);
- }
-
- *unpack_data= data;
- *unpack_len= orglen;
-
- DBUG_PRINT("exit", ("frmdata: 0x%lx len: %lu", (long) *unpack_data,
- (ulong) *unpack_len));
- DBUG_RETURN(0);
-}
-#endif /* HAVE_COMPRESS */
diff --git a/dep/mysqllite/mysys/my_conio.c b/dep/mysqllite/mysys/my_conio.c
deleted file mode 100644
index 5dbd31193a9..00000000000
--- a/dep/mysqllite/mysys/my_conio.c
+++ /dev/null
@@ -1,222 +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"
-
-#ifdef __WIN__
-
-static HANDLE my_coninpfh= 0; /* console input */
-
-/*
- functions my_pthread_auto_mutex_lock & my_pthread_auto_mutex_free
- are experimental at this moment, they are intended to bring
- ability of protecting code sections without necessity to explicitly
- initialize synchronization object in one of threads
-
- if found useful they are to be exported in mysys
-*/
-
-
-/*
- int my_pthread_auto_mutex_lock(HANDLE* ph, const char* name,
- int id, int time)
- NOTES
- creates a mutex with given name and tries to lock it time msec.
- mutex name is appended with id to allow system wide or process wide
- locks. Handle to created mutex returned in ph argument.
-
- RETURN
- 0 thread owns mutex
- <>0 error
-*/
-
-static
-int my_pthread_auto_mutex_lock(HANDLE* ph, const char* name, int id, int time)
-{
- int res;
- char tname[FN_REFLEN];
-
- sprintf(tname, "%s-%08X", name, id);
-
- *ph= CreateMutex(NULL, FALSE, tname);
- if (*ph == NULL)
- return GetLastError();
-
- res= WaitForSingleObject(*ph, time);
-
- if (res == WAIT_TIMEOUT)
- return ERROR_SEM_TIMEOUT;
-
- if (res == WAIT_FAILED)
- return GetLastError();
-
- return 0;
-}
-
-/*
- int my_pthread_auto_mutex_free(HANDLE* ph)
-
- NOTES
- releases a mutex.
-
- RETURN
- 0 thread released mutex
- <>0 error
-
-*/
-static
-int my_pthread_auto_mutex_free(HANDLE* ph)
-{
- if (*ph)
- {
- ReleaseMutex(*ph);
- CloseHandle(*ph);
- *ph= NULL;
- }
-
- return 0;
-}
-
-
-#define pthread_auto_mutex_decl(name) \
- HANDLE __h##name= NULL;
-
-#define pthread_auto_mutex_lock(name, proc, time) \
- my_pthread_auto_mutex_lock(&__h##name, #name, (proc), (time))
-
-#define pthread_auto_mutex_free(name) \
- my_pthread_auto_mutex_free(&__h##name)
-
-
-/*
- char* my_cgets()
-
- NOTES
- Replaces _cgets from libc to support input of more than 255 chars.
- Reads from the console via ReadConsole into buffer which
- should be at least clen characters.
- Actual length of string returned in plen.
-
- WARNING
- my_cgets() does NOT check the pushback character buffer (i.e., _chbuf).
- Thus, my_cgets() will not return any character that is pushed back by
- the _ungetch() call.
-
- RETURN
- string pointer ok
- NULL Error
-
-*/
-
-char* my_cgets(char *buffer, size_t clen, size_t* plen)
-{
- ULONG state;
- char *result;
- DWORD plen_res;
- CONSOLE_SCREEN_BUFFER_INFO csbi;
-
- pthread_auto_mutex_decl(my_conio_cs);
-
- /* lock the console for the current process*/
- if (pthread_auto_mutex_lock(my_conio_cs, GetCurrentProcessId(), INFINITE))
- {
- /* can not lock console */
- pthread_auto_mutex_free(my_conio_cs);
- return NULL;
- }
-
- /* init console input */
- if (my_coninpfh == 0)
- {
- /* same handle will be used until process termination */
- my_coninpfh= CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, 0, NULL);
- }
-
- if (my_coninpfh == INVALID_HANDLE_VALUE)
- {
- /* unlock the console */
- pthread_auto_mutex_free(my_conio_cs);
- return(NULL);
- }
-
- GetConsoleMode((HANDLE)my_coninpfh, &state);
- SetConsoleMode((HANDLE)my_coninpfh, ENABLE_LINE_INPUT |
- ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT);
-
- GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
-
- /*
- there is no known way to determine allowed buffer size for input
- though it is known it should not be more than 64K
- so we cut 64K and try first size of screen buffer
- if it is still to large we cut half of it and try again
- later we may want to cycle from min(clen, 65535) to allowed size
- with small decrement to determine exact allowed buffer
- */
- clen= min(clen, 65535);
- do
- {
- clen= min(clen, (size_t) csbi.dwSize.X*csbi.dwSize.Y);
- if (!ReadConsole((HANDLE)my_coninpfh, (LPVOID)buffer, (DWORD) clen - 1, &plen_res,
- NULL))
- {
- result= NULL;
- clen>>= 1;
- }
- else
- {
- result= buffer;
- break;
- }
- }
- while (GetLastError() == ERROR_NOT_ENOUGH_MEMORY);
- *plen= plen_res;
-
- /* We go here on error reading the string (Ctrl-C for example) */
- if (!*plen)
- result= NULL; /* purecov: inspected */
-
- if (result != NULL)
- {
- if (*plen > 1 && buffer[*plen - 2] == '\r')
- {
- *plen= *plen - 2;
- }
- else
- {
- if (*plen > 0 && buffer[*plen - 1] == '\r')
- {
- char tmp[3];
- int tmplen= sizeof(tmp);
-
- *plen= *plen - 1;
- /* read /n left in the buffer */
- ReadConsole((HANDLE)my_coninpfh, (LPVOID)tmp, tmplen, &tmplen, NULL);
- }
- }
- buffer[*plen]= '\0';
- }
-
- SetConsoleMode((HANDLE)my_coninpfh, state);
- /* unlock the console */
- pthread_auto_mutex_free(my_conio_cs);
-
- return result;
-}
-
-#endif /* __WIN__ */
diff --git a/dep/mysqllite/mysys/my_copy.c b/dep/mysqllite/mysys/my_copy.c
deleted file mode 100644
index 35324dd4cef..00000000000
--- a/dep/mysqllite/mysys/my_copy.c
+++ /dev/null
@@ -1,144 +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 <my_dir.h> /* for stat */
-#include <m_string.h>
-#include "mysys_err.h"
-#if defined(HAVE_UTIME_H)
-#include <utime.h>
-#elif defined(HAVE_SYS_UTIME_H)
-#include <sys/utime.h>
-#elif !defined(HPUX10)
-#include <time.h>
-struct utimbuf {
- time_t actime;
- time_t modtime;
-};
-#endif
-
-
-/*
- int my_copy(const char *from, const char *to, myf MyFlags)
-
- NOTES
- Ordinary ownership and accesstimes are copied from 'from-file'
- If MyFlags & MY_HOLD_ORIGINAL_MODES is set and to-file exists then
- the modes of to-file isn't changed
- If MyFlags & MY_DONT_OVERWRITE_FILE is set, we will give an error
- if the file existed.
-
- WARNING
- Don't set MY_FNABP or MY_NABP bits on when calling this function !
-
- RETURN
- 0 ok
- # Error
-
-*/
-
-int my_copy(const char *from, const char *to, myf MyFlags)
-{
- size_t Count;
- my_bool new_file_stat= 0; /* 1 if we could stat "to" */
- int create_flag;
- File from_file,to_file;
- uchar buff[IO_SIZE];
- MY_STAT stat_buff,new_stat_buff;
- DBUG_ENTER("my_copy");
- DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags));
-
- from_file=to_file= -1;
- DBUG_ASSERT(!(MyFlags & (MY_FNABP | MY_NABP))); /* for my_read/my_write */
- if (MyFlags & MY_HOLD_ORIGINAL_MODES) /* Copy stat if possible */
- new_file_stat= test(my_stat((char*) to, &new_stat_buff, MYF(0)));
-
- if ((from_file=my_open(from,O_RDONLY | O_SHARE,MyFlags)) >= 0)
- {
- if (!my_stat(from, &stat_buff, MyFlags))
- {
- my_errno=errno;
- goto err;
- }
- if (MyFlags & MY_HOLD_ORIGINAL_MODES && new_file_stat)
- stat_buff=new_stat_buff;
- create_flag= (MyFlags & MY_DONT_OVERWRITE_FILE) ? O_EXCL : O_TRUNC;
-
- if ((to_file= my_create(to,(int) stat_buff.st_mode,
- O_WRONLY | create_flag | O_BINARY | O_SHARE,
- MyFlags)) < 0)
- goto err;
-
- while ((Count=my_read(from_file, buff, sizeof(buff), MyFlags)) != 0)
- {
- if (Count == (uint) -1 ||
- my_write(to_file,buff,Count,MYF(MyFlags | MY_NABP)))
- goto err;
- }
-
- /* sync the destination file */
- if (MyFlags & MY_SYNC)
- {
- if (my_sync(to_file, MyFlags))
- goto err;
- }
-
- if (my_close(from_file,MyFlags) | my_close(to_file,MyFlags))
- DBUG_RETURN(-1); /* Error on close */
-
- /* Copy modes if possible */
-
- if (MyFlags & MY_HOLD_ORIGINAL_MODES && !new_file_stat)
- DBUG_RETURN(0); /* File copyed but not stat */
- /* Copy modes */
- if (chmod(to, stat_buff.st_mode & 07777))
- {
- my_errno= errno;
- if (MyFlags & (MY_FAE+MY_WME))
- my_error(EE_CHANGE_PERMISSIONS, MYF(ME_BELL+ME_WAITTANG), from, errno);
- goto err;
- }
-#if !defined(__WIN__)
- /* Copy ownership */
- if (chown(to, stat_buff.st_uid, stat_buff.st_gid))
- {
- my_errno= errno;
- if (MyFlags & (MY_FAE+MY_WME))
- my_error(EE_CHANGE_OWNERSHIP, MYF(ME_BELL+ME_WAITTANG), from, errno);
- goto err;
- }
-#endif
-
- if (MyFlags & MY_COPYTIME)
- {
- struct utimbuf timep;
- timep.actime = stat_buff.st_atime;
- timep.modtime = stat_buff.st_mtime;
- (void) utime((char*) to, &timep); /* last accessed and modified times */
- }
-
- DBUG_RETURN(0);
- }
-
-err:
- if (from_file >= 0) (void) my_close(from_file,MyFlags);
- if (to_file >= 0)
- {
- (void) my_close(to_file, MyFlags);
- /* attempt to delete the to-file we've partially written */
- (void) my_delete(to, MyFlags);
- }
- DBUG_RETURN(-1);
-} /* my_copy */
diff --git a/dep/mysqllite/mysys/my_create.c b/dep/mysqllite/mysys/my_create.c
deleted file mode 100644
index 49529f9b7b5..00000000000
--- a/dep/mysqllite/mysys/my_create.c
+++ /dev/null
@@ -1,73 +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 <my_dir.h>
-#include "mysys_err.h"
-#include <errno.h>
-#include <my_sys.h>
-#if defined(_WIN32)
-#include <share.h>
-#endif
-
- /*
- ** Create a new file
- ** Arguments:
- ** Path-name of file
- ** Read | write on file (umask value)
- ** Read & Write on open file
- ** Special flags
- */
-
-
-File my_create(const char *FileName, int CreateFlags, int access_flags,
- myf MyFlags)
-{
- int fd, rc;
- DBUG_ENTER("my_create");
- DBUG_PRINT("my",("Name: '%s' CreateFlags: %d AccessFlags: %d MyFlags: %d",
- FileName, CreateFlags, access_flags, MyFlags));
-#if defined(_WIN32)
- fd= my_win_open(FileName, access_flags | O_CREAT);
-#else
- fd= open((char *) FileName, access_flags | O_CREAT,
- CreateFlags ? CreateFlags : my_umask);
-#endif
-
- if ((MyFlags & MY_SYNC_DIR) && (fd >=0) &&
- my_sync_dir_by_file(FileName, MyFlags))
- {
- my_close(fd, MyFlags);
- fd= -1;
- }
-
- rc= my_register_filename(fd, FileName, FILE_BY_CREATE,
- EE_CANTCREATEFILE, MyFlags);
- /*
- my_register_filename() may fail on some platforms even if the call to
- *open() above succeeds. In this case, don't leave the stale file because
- callers assume the file to not exist if my_create() fails, so they don't
- do any cleanups.
- */
- if (unlikely(fd >= 0 && rc < 0))
- {
- int tmp= my_errno;
- my_close(fd, MyFlags);
- my_delete(FileName, MyFlags);
- my_errno= tmp;
- }
-
- DBUG_RETURN(rc);
-} /* my_create */
diff --git a/dep/mysqllite/mysys/my_delete.c b/dep/mysqllite/mysys/my_delete.c
deleted file mode 100644
index 4a23fedb5ab..00000000000
--- a/dep/mysqllite/mysys/my_delete.c
+++ /dev/null
@@ -1,125 +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"
-#include <my_sys.h>
-
-int my_delete(const char *name, myf MyFlags)
-{
- int err;
- DBUG_ENTER("my_delete");
- DBUG_PRINT("my",("name %s MyFlags %d", name, MyFlags));
-
- if ((err = unlink(name)) == -1)
- {
- my_errno=errno;
- if (MyFlags & (MY_FAE+MY_WME))
- my_error(EE_DELETE,MYF(ME_BELL+ME_WAITTANG+(MyFlags & ME_NOINPUT)),
- name,errno);
- }
- else if ((MyFlags & MY_SYNC_DIR) &&
- my_sync_dir_by_file(name, MyFlags))
- err= -1;
- DBUG_RETURN(err);
-} /* my_delete */
-
-#if defined(__WIN__)
-/**
- Delete file which is possibly not closed.
-
- This function is intended to be used exclusively as a temporal solution
- for Win NT in case when it is needed to delete a not closed file (note
- that the file must be opened everywhere with FILE_SHARE_DELETE mode).
- Deleting not-closed files can not be supported on Win 98|ME (and because
- of that is considered harmful).
-
- The function deletes the file with its preliminary renaming. This is
- because when not-closed share-delete file is deleted it still lives on
- a disk until it will not be closed everwhere. This may conflict with an
- attempt to create a new file with the same name. The deleted file is
- renamed to <name>.<num>.deleted where <name> - the initial name of the
- file, <num> - a hexadecimal number chosen to make the temporal name to
- be unique.
-
- @param the name of the being deleted file
- @param the flags instructing how to react on an error internally in
- the function
-
- @note The per-thread @c my_errno holds additional info for a caller to
- decide how critical the error can be.
-
- @retval
- 0 ok
- @retval
- 1 error
-
-
-*/
-int nt_share_delete(const char *name, myf MyFlags)
-{
- char buf[MAX_PATH + 20];
- ulong cnt;
- DBUG_ENTER("nt_share_delete");
- DBUG_PRINT("my",("name %s MyFlags %d", name, MyFlags));
-
- for (cnt= GetTickCount(); cnt; cnt--)
- {
- errno= 0;
- sprintf(buf, "%s.%08X.deleted", name, cnt);
- if (MoveFile(name, buf))
- break;
-
- if ((errno= GetLastError()) == ERROR_ALREADY_EXISTS)
- continue;
-
- /* This happened during tests with MERGE tables. */
- if (errno == ERROR_ACCESS_DENIED)
- continue;
-
- DBUG_PRINT("warning", ("Failed to rename %s to %s, errno: %d",
- name, buf, errno));
- break;
- }
-
- if (errno == ERROR_FILE_NOT_FOUND)
- {
- my_errno= ENOENT; // marking, that `name' doesn't exist
- }
- else if (errno == 0)
- {
- if (DeleteFile(buf))
- DBUG_RETURN(0);
- /*
- The below is more complicated than necessary. For some reason, the
- assignment to my_errno clears the error number, which is retrieved
- by GetLastError() (VC2005EE). Assigning to errno first, allows to
- retrieve the correct value.
- */
- errno= GetLastError();
- if (errno == 0)
- my_errno= ENOENT; // marking, that `buf' doesn't exist
- else
- my_errno= errno;
- }
- else
- my_errno= errno;
-
- if (MyFlags & (MY_FAE+MY_WME))
- my_error(EE_DELETE, MYF(ME_BELL + ME_WAITTANG + (MyFlags & ME_NOINPUT)),
- name, my_errno);
- DBUG_RETURN(-1);
-}
-#endif
diff --git a/dep/mysqllite/mysys/my_div.c b/dep/mysqllite/mysys/my_div.c
deleted file mode 100644
index d29d3668852..00000000000
--- a/dep/mysqllite/mysys/my_div.c
+++ /dev/null
@@ -1,37 +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"
-
-/*
- Get filename of file
-
- SYNOPSIS
- my_filename()
- fd File descriptor
-*/
-
-char * my_filename(File fd)
-{
- DBUG_ENTER("my_filename");
- if ((uint) fd >= (uint) my_file_limit)
- DBUG_RETURN((char*) "UNKNOWN");
- if (fd >= 0 && my_file_info[fd].type != UNOPEN)
- {
- DBUG_RETURN(my_file_info[fd].name);
- }
- else
- DBUG_RETURN((char*) "UNOPENED"); /* Debug message */
-}
diff --git a/dep/mysqllite/mysys/my_error.c b/dep/mysqllite/mysys/my_error.c
deleted file mode 100644
index fa62cc604b6..00000000000
--- a/dep/mysqllite/mysys/my_error.c
+++ /dev/null
@@ -1,290 +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"
-#include <m_string.h>
-#include <stdarg.h>
-#include <m_ctype.h>
-
-/* Max length of a error message. Should be kept in sync with MYSQL_ERRMSG_SIZE. */
-#define ERRMSGSIZE (512)
-
-/* Define some external variables for error handling */
-
-/*
- WARNING!
- my_error family functions have to be used according following rules:
- - if message have not parameters use my_message(ER_CODE, ER(ER_CODE), MYF(N))
- - if message registered use my_error(ER_CODE, MYF(N), ...).
- - With some special text of errror message use:
- my_printf_error(ER_CODE, format, MYF(N), ...)
-*/
-
-/*
- Message texts are registered into a linked list of 'my_err_head' structs.
- Each struct contains (1.) an array of pointers to C character strings with
- '\0' termination, (2.) the error number for the first message in the array
- (array index 0) and (3.) the error number for the last message in the array
- (array index (last - first)).
- The array may contain gaps with NULL pointers and pointers to empty strings.
- Both kinds of gaps will be translated to "Unknown error %d.", if my_error()
- is called with a respective error number.
- The list of header structs is sorted in increasing order of error numbers.
- Negative error numbers are allowed. Overlap of error numbers is not allowed.
- Not registered error numbers will be translated to "Unknown error %d.".
-*/
-static struct my_err_head
-{
- struct my_err_head *meh_next; /* chain link */
- const char** (*get_errmsgs) (); /* returns error message format */
- int meh_first; /* error number matching array slot 0 */
- int meh_last; /* error number matching last slot */
-} my_errmsgs_globerrs = {NULL, get_global_errmsgs, EE_ERROR_FIRST, EE_ERROR_LAST};
-
-static struct my_err_head *my_errmsgs_list= &my_errmsgs_globerrs;
-
-
-/*
- Error message to user
-
- SYNOPSIS
- my_error()
- nr Errno
- MyFlags Flags
- ... variable list
-
-*/
-
-void my_error(int nr, myf MyFlags, ...)
-{
- const char *format;
- struct my_err_head *meh_p;
- va_list args;
- char ebuff[ERRMSGSIZE];
- 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. */
- for (meh_p= my_errmsgs_list; meh_p; meh_p= meh_p->meh_next)
- if (nr <= meh_p->meh_last)
- break;
-
- /* get the error message string. Default, if NULL or empty string (""). */
- if (! (format= (meh_p && (nr >= meh_p->meh_first)) ?
- meh_p->get_errmsgs()[nr - meh_p->meh_first] : NULL) || ! *format)
- (void) my_snprintf (ebuff, sizeof(ebuff), "Unknown error %d", nr);
- else
- {
- va_start(args,MyFlags);
- (void) my_vsnprintf_ex(&my_charset_utf8_general_ci, ebuff,
- sizeof(ebuff), format, args);
- va_end(args);
- }
- (*error_handler_hook)(nr, ebuff, MyFlags);
- DBUG_VOID_RETURN;
-}
-
-
-/*
- Error as printf
-
- SYNOPSIS
- my_printf_error()
- error Errno
- format Format string
- MyFlags Flags
- ... variable list
-*/
-
-void my_printf_error(uint error, const char *format, myf MyFlags, ...)
-{
- va_list args;
- char ebuff[ERRMSGSIZE];
- DBUG_ENTER("my_printf_error");
- DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d Format: %s",
- error, MyFlags, errno, format));
-
- va_start(args,MyFlags);
- (void) my_vsnprintf_ex(&my_charset_utf8_general_ci, ebuff,
- sizeof(ebuff), format, args);
- va_end(args);
- (*error_handler_hook)(error, ebuff, MyFlags);
- DBUG_VOID_RETURN;
-}
-
-/*
- Error with va_list
-
- SYNOPSIS
- my_printv_error()
- error Errno
- format Format string
- MyFlags Flags
- ... variable list
-*/
-
-void my_printv_error(uint error, const char *format, myf MyFlags, va_list ap)
-{
- char ebuff[ERRMSGSIZE];
- DBUG_ENTER("my_printv_error");
- DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d format: %s",
- error, MyFlags, errno, format));
-
- (void) my_vsnprintf(ebuff, sizeof(ebuff), format, ap);
- (*error_handler_hook)(error, ebuff, MyFlags);
- DBUG_VOID_RETURN;
-}
-
-/*
- Give message using error_handler_hook
-
- SYNOPSIS
- my_message()
- error Errno
- str Error message
- MyFlags Flags
-*/
-
-void my_message(uint error, const char *str, register myf MyFlags)
-{
- (*error_handler_hook)(error, str, MyFlags);
-}
-
-
-/*
- Register error messages for use with my_error().
-
- SYNOPSIS
- my_error_register()
- errmsgs array of pointers to error messages
- first error number of first message in the array
- last error number of last message in the array
-
- DESCRIPTION
- The pointer array is expected to contain addresses to NUL-terminated
- C character strings. The array contains (last - first + 1) pointers.
- NULL pointers and empty strings ("") are allowed. These will be mapped to
- "Unknown error" when my_error() is called with a matching error number.
- This function registers the error numbers 'first' to 'last'.
- No overlapping with previously registered error numbers is allowed.
-
- RETURN
- 0 OK
- != 0 Error
-*/
-
-int my_error_register(const char** (*get_errmsgs) (), int first, int last)
-{
- struct my_err_head *meh_p;
- struct my_err_head **search_meh_pp;
-
- /* Allocate a new header structure. */
- if (! (meh_p= (struct my_err_head*) my_malloc(sizeof(struct my_err_head),
- MYF(MY_WME))))
- return 1;
- meh_p->get_errmsgs= get_errmsgs;
- meh_p->meh_first= first;
- meh_p->meh_last= last;
-
- /* Search for the right position in the list. */
- for (search_meh_pp= &my_errmsgs_list;
- *search_meh_pp;
- search_meh_pp= &(*search_meh_pp)->meh_next)
- {
- if ((*search_meh_pp)->meh_last > first)
- break;
- }
-
- /* Error numbers must be unique. No overlapping is allowed. */
- if (*search_meh_pp && ((*search_meh_pp)->meh_first <= last))
- {
- my_free(meh_p);
- return 1;
- }
-
- /* Insert header into the chain. */
- meh_p->meh_next= *search_meh_pp;
- *search_meh_pp= meh_p;
- return 0;
-}
-
-
-/*
- Unregister formerly registered error messages.
-
- SYNOPSIS
- my_error_unregister()
- first error number of first message
- last error number of last message
-
- DESCRIPTION
- This function unregisters the error numbers 'first' to 'last'.
- These must have been previously registered by my_error_register().
- 'first' and 'last' must exactly match the registration.
- If a matching registration is present, the header is removed from the
- list and the pointer to the error messages pointers array is returned.
- Otherwise, NULL is returned.
-
- RETURN
- non-NULL OK, returns address of error messages pointers array.
- NULL Error, no such number range registered.
-*/
-
-const char **my_error_unregister(int first, int last)
-{
- struct my_err_head *meh_p;
- struct my_err_head **search_meh_pp;
- const char **errmsgs;
-
- /* Search for the registration in the list. */
- for (search_meh_pp= &my_errmsgs_list;
- *search_meh_pp;
- search_meh_pp= &(*search_meh_pp)->meh_next)
- {
- if (((*search_meh_pp)->meh_first == first) &&
- ((*search_meh_pp)->meh_last == last))
- break;
- }
- if (! *search_meh_pp)
- return NULL;
-
- /* Remove header from the chain. */
- meh_p= *search_meh_pp;
- *search_meh_pp= meh_p->meh_next;
-
- /* Save the return value and free the header. */
- errmsgs= meh_p->get_errmsgs();
- my_free(meh_p);
-
- return errmsgs;
-}
-
-
-void my_error_unregister_all(void)
-{
- struct my_err_head *cursor, *saved_next;
-
- for (cursor= my_errmsgs_globerrs.meh_next; cursor != NULL; cursor= saved_next)
- {
- /* We need this ptr, but we're about to free its container, so save it. */
- saved_next= cursor->meh_next;
-
- my_free(cursor);
- }
- my_errmsgs_globerrs.meh_next= NULL; /* Freed in first iteration above. */
-
- my_errmsgs_list= &my_errmsgs_globerrs;
-}
diff --git a/dep/mysqllite/mysys/my_file.c b/dep/mysqllite/mysys/my_file.c
deleted file mode 100644
index e4b7cd7779f..00000000000
--- a/dep/mysqllite/mysys/my_file.c
+++ /dev/null
@@ -1,135 +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 "my_static.h"
-#include <m_string.h>
-
-/*
- set how many open files we want to be able to handle
-
- SYNOPSIS
- set_maximum_open_files()
- max_file_limit Files to open
-
- NOTES
- The request may not fulfilled becasue of system limitations
-
- RETURN
- Files available to open.
- May be more or less than max_file_limit!
-*/
-
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
-
-#ifndef RLIM_INFINITY
-#define RLIM_INFINITY ((uint) 0xffffffff)
-#endif
-
-static uint set_max_open_files(uint max_file_limit)
-{
- struct rlimit rlimit;
- uint old_cur;
- DBUG_ENTER("set_max_open_files");
- DBUG_PRINT("enter",("files: %u", max_file_limit));
-
- if (!getrlimit(RLIMIT_NOFILE,&rlimit))
- {
- old_cur= (uint) rlimit.rlim_cur;
- DBUG_PRINT("info", ("rlim_cur: %u rlim_max: %u",
- (uint) rlimit.rlim_cur,
- (uint) rlimit.rlim_max));
- if (rlimit.rlim_cur == RLIM_INFINITY)
- rlimit.rlim_cur = max_file_limit;
- if (rlimit.rlim_cur >= max_file_limit)
- DBUG_RETURN(rlimit.rlim_cur); /* purecov: inspected */
- rlimit.rlim_cur= rlimit.rlim_max= max_file_limit;
- if (setrlimit(RLIMIT_NOFILE, &rlimit))
- max_file_limit= old_cur; /* Use original value */
- else
- {
- rlimit.rlim_cur= 0; /* Safety if next call fails */
- (void) getrlimit(RLIMIT_NOFILE,&rlimit);
- DBUG_PRINT("info", ("rlim_cur: %u", (uint) rlimit.rlim_cur));
- if (rlimit.rlim_cur) /* If call didn't fail */
- max_file_limit= (uint) rlimit.rlim_cur;
- }
- }
- DBUG_PRINT("exit",("max_file_limit: %u", max_file_limit));
- DBUG_RETURN(max_file_limit);
-}
-
-#else
-static uint set_max_open_files(uint max_file_limit)
-{
- /* We don't know the limit. Return best guess */
- return min(max_file_limit, OS_FILE_LIMIT);
-}
-#endif
-
-
-/*
- Change number of open files
-
- SYNOPSIS:
- my_set_max_open_files()
- files Number of requested files
-
- RETURN
- number of files available for open
-*/
-
-uint my_set_max_open_files(uint files)
-{
- struct st_my_file_info *tmp;
- DBUG_ENTER("my_set_max_open_files");
- DBUG_PRINT("enter",("files: %u my_file_limit: %u", files, my_file_limit));
-
- files+= MY_FILE_MIN;
- files= set_max_open_files(min(files, OS_FILE_LIMIT));
- if (files <= MY_NFILE)
- DBUG_RETURN(files);
-
- if (!(tmp= (struct st_my_file_info*) my_malloc(sizeof(*tmp) * files,
- MYF(MY_WME))))
- DBUG_RETURN(MY_NFILE);
-
- /* Copy any initialized files */
- 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;
- DBUG_PRINT("exit",("files: %u", files));
- DBUG_RETURN(files);
-}
-
-
-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(my_file_info);
- my_file_info= my_file_info_default;
- my_file_limit= MY_NFILE;
- }
- DBUG_VOID_RETURN;
-}
diff --git a/dep/mysqllite/mysys/my_fopen.c b/dep/mysqllite/mysys/my_fopen.c
deleted file mode 100644
index e184c8308fc..00000000000
--- a/dep/mysqllite/mysys/my_fopen.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 "my_static.h"
-#include <errno.h>
-#include "mysys_err.h"
-
-#if defined(__FreeBSD__)
-extern int getosreldate(void);
-#endif
-
-static void make_ftype(char * to,int flag);
-
-/*
- Open a file as stream
-
- SYNOPSIS
- my_fopen()
- FileName Path-name of file
- Flags Read | write | append | trunc (like for open())
- MyFlags Flags for handling errors
-
- RETURN
- 0 Error
- # File handler
-*/
-
-FILE *my_fopen(const char *filename, int flags, myf MyFlags)
-{
- FILE *fd;
- char type[5];
- DBUG_ENTER("my_fopen");
- DBUG_PRINT("my",("Name: '%s' flags: %d MyFlags: %d",
- filename, flags, MyFlags));
-
- make_ftype(type,flags);
-
-#ifdef _WIN32
- fd= my_win_fopen(filename, type);
-#else
- fd= fopen(filename, type);
-#endif
- if (fd != 0)
- {
- /*
- The test works if MY_NFILE < 128. The problem is that fileno() is char
- on some OS (SUNOS). Actually the filename save isn't that important
- so we can ignore if this doesn't work.
- */
-
- int filedesc= my_fileno(fd);
- if ((uint)filedesc >= my_file_limit)
- {
- thread_safe_increment(my_stream_opened,&THR_LOCK_open);
- DBUG_RETURN(fd); /* safeguard */
- }
- mysql_mutex_lock(&THR_LOCK_open);
- if ((my_file_info[filedesc].name= (char*)
- my_strdup(filename,MyFlags)))
- {
- my_stream_opened++;
- my_file_total_opened++;
- my_file_info[filedesc].type= STREAM_BY_FOPEN;
- mysql_mutex_unlock(&THR_LOCK_open);
- DBUG_PRINT("exit",("stream: 0x%lx", (long) fd));
- DBUG_RETURN(fd);
- }
- mysql_mutex_unlock(&THR_LOCK_open);
- (void) my_fclose(fd,MyFlags);
- my_errno=ENOMEM;
- }
- else
- my_errno=errno;
- DBUG_PRINT("error",("Got error %d on open",my_errno));
- if (MyFlags & (MY_FFNF | MY_FAE | MY_WME))
- my_error((flags & O_RDONLY) || (flags == O_RDONLY ) ? EE_FILENOTFOUND :
- EE_CANTCREATEFILE,
- MYF(ME_BELL+ME_WAITTANG), filename, my_errno);
- DBUG_RETURN((FILE*) 0);
-} /* my_fopen */
-
-
-#if defined(_WIN32)
-
-static FILE *my_win_freopen(const char *path, const char *mode, FILE *stream)
-{
- int handle_fd, fd= _fileno(stream);
- HANDLE osfh;
-
- DBUG_ASSERT(path && stream);
-
- /* Services don't have stdout/stderr on Windows, so _fileno returns -1. */
- if (fd < 0)
- {
- if (!freopen(path, mode, stream))
- return NULL;
-
- fd= _fileno(stream);
- }
-
- if ((osfh= CreateFile(path, GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE |
- FILE_SHARE_DELETE, NULL,
- OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,
- NULL)) == INVALID_HANDLE_VALUE)
- return NULL;
-
- if ((handle_fd= _open_osfhandle((intptr_t)osfh,
- _O_APPEND | _O_TEXT)) == -1)
- {
- CloseHandle(osfh);
- return NULL;
- }
-
- if (_dup2(handle_fd, fd) < 0)
- {
- CloseHandle(osfh);
- return NULL;
- }
-
- _close(handle_fd);
-
- return stream;
-}
-
-#elif defined(__FreeBSD__)
-
-/* No close operation hook. */
-
-static int no_close(void *cookie __attribute__((unused)))
-{
- return 0;
-}
-
-/*
- A hack around a race condition in the implementation of freopen.
-
- The race condition steams from the fact that the current fd of
- the stream is closed before its number is used to duplicate the
- new file descriptor. This defeats the desired atomicity of the
- close and duplicate of dup2().
-
- See PR number 79887 for reference:
- http://www.freebsd.org/cgi/query-pr.cgi?pr=79887
-*/
-
-static FILE *my_freebsd_freopen(const char *path, const char *mode, FILE *stream)
-{
- int old_fd;
- FILE *result;
-
- flockfile(stream);
-
- old_fd= fileno(stream);
-
- /* Use a no operation close hook to avoid having the fd closed. */
- stream->_close= no_close;
-
- /* Relies on the implicit dup2 to close old_fd. */
- result= freopen(path, mode, stream);
-
- /* If successful, the _close hook was replaced. */
-
- if (result == NULL)
- close(old_fd);
- else
- funlockfile(result);
-
- return result;
-}
-
-#endif
-
-
-/**
- Change the file associated with a file stream.
-
- @param path Path to file.
- @param mode Mode of the stream.
- @param stream File stream.
-
- @note
- This function is used to redirect stdout and stderr to a file and
- subsequently to close and reopen that file for log rotation.
-
- @retval A FILE pointer on success. Otherwise, NULL.
-*/
-
-FILE *my_freopen(const char *path, const char *mode, FILE *stream)
-{
- FILE *result;
-
-#if defined(_WIN32)
- result= my_win_freopen(path, mode, stream);
-#elif defined(__FreeBSD__)
- /*
- XXX: Once the fix is ported to the stable releases, this should
- be dependent upon the specific FreeBSD versions. Check at:
- http://www.freebsd.org/cgi/query-pr.cgi?pr=79887
- */
- if (getosreldate() > 900027)
- result= freopen(path, mode, stream);
- else
- result= my_freebsd_freopen(path, mode, stream);
-#else
- result= freopen(path, mode, stream);
-#endif
-
- return result;
-}
-
-
-/* Close a stream */
-int my_fclose(FILE *fd, myf MyFlags)
-{
- int err,file;
- DBUG_ENTER("my_fclose");
- DBUG_PRINT("my",("stream: 0x%lx MyFlags: %d", (long) fd, MyFlags));
-
- mysql_mutex_lock(&THR_LOCK_open);
- file= my_fileno(fd);
-#ifndef _WIN32
- err= fclose(fd);
-#else
- err= my_win_fclose(fd);
-#endif
- if(err < 0)
- {
- my_errno=errno;
- if (MyFlags & (MY_FAE | MY_WME))
- my_error(EE_BADCLOSE, MYF(ME_BELL+ME_WAITTANG),
- my_filename(file),errno);
- }
- else
- my_stream_opened--;
- if ((uint) file < my_file_limit && my_file_info[file].type != UNOPEN)
- {
- my_file_info[file].type = UNOPEN;
- my_free(my_file_info[file].name);
- }
- mysql_mutex_unlock(&THR_LOCK_open);
- DBUG_RETURN(err);
-} /* my_fclose */
-
-
- /* Make a stream out of a file handle */
- /* Name may be 0 */
-
-FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags)
-{
- FILE *fd;
- char type[5];
- DBUG_ENTER("my_fdopen");
- DBUG_PRINT("my",("Fd: %d Flags: %d MyFlags: %d",
- Filedes, Flags, MyFlags));
-
- make_ftype(type,Flags);
-#ifdef _WIN32
- fd= my_win_fdopen(Filedes, type);
-#else
- fd= fdopen(Filedes, type);
-#endif
- if (!fd)
- {
- my_errno=errno;
- if (MyFlags & (MY_FAE | MY_WME))
- my_error(EE_CANT_OPEN_STREAM, MYF(ME_BELL+ME_WAITTANG),errno);
- }
- else
- {
- mysql_mutex_lock(&THR_LOCK_open);
- my_stream_opened++;
- if ((uint) Filedes < (uint) my_file_limit)
- {
- if (my_file_info[Filedes].type != UNOPEN)
- {
- my_file_opened--; /* File is opened with my_open ! */
- }
- else
- {
- my_file_info[Filedes].name= my_strdup(name,MyFlags);
- }
- my_file_info[Filedes].type = STREAM_BY_FDOPEN;
- }
- mysql_mutex_unlock(&THR_LOCK_open);
- }
-
- DBUG_PRINT("exit",("stream: 0x%lx", (long) fd));
- DBUG_RETURN(fd);
-} /* my_fdopen */
-
-
-/*
- Make a fopen() typestring from a open() type bitmap
-
- SYNOPSIS
- make_ftype()
- to String for fopen() is stored here
- flag Flag used by open()
-
- IMPLEMENTATION
- This routine attempts to find the best possible match
- between a numeric option and a string option that could be
- fed to fopen. There is not a 1 to 1 mapping between the two.
-
- NOTE
- On Unix, O_RDONLY is usually 0
-
- MAPPING
- r == O_RDONLY
- w == O_WRONLY|O_TRUNC|O_CREAT
- a == O_WRONLY|O_APPEND|O_CREAT
- r+ == O_RDWR
- w+ == O_RDWR|O_TRUNC|O_CREAT
- a+ == O_RDWR|O_APPEND|O_CREAT
-*/
-
-static void make_ftype(register char * to, register int flag)
-{
- /* check some possible invalid combinations */
- DBUG_ASSERT((flag & (O_TRUNC | O_APPEND)) != (O_TRUNC | O_APPEND));
- DBUG_ASSERT((flag & (O_WRONLY | O_RDWR)) != (O_WRONLY | O_RDWR));
-
- if ((flag & (O_RDONLY|O_WRONLY)) == O_WRONLY)
- *to++= (flag & O_APPEND) ? 'a' : 'w';
- else if (flag & O_RDWR)
- {
- /* Add '+' after theese */
- if (flag & (O_TRUNC | O_CREAT))
- *to++= 'w';
- else if (flag & O_APPEND)
- *to++= 'a';
- else
- *to++= 'r';
- *to++= '+';
- }
- else
- *to++= 'r';
-
-#if FILE_BINARY /* If we have binary-files */
- if (flag & FILE_BINARY)
- *to++='b';
-#endif
- *to='\0';
-} /* make_ftype */
diff --git a/dep/mysqllite/mysys/my_fstream.c b/dep/mysqllite/mysys/my_fstream.c
deleted file mode 100644
index 83cb0d261c0..00000000000
--- a/dep/mysqllite/mysys/my_fstream.c
+++ /dev/null
@@ -1,194 +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 */
-
-/* USE_MY_STREAM isn't set because we can't thrust my_fclose! */
-
-#include "mysys_priv.h"
-#include "mysys_err.h"
-#include <errno.h>
-#include <stdio.h>
-
-#ifdef HAVE_FSEEKO
-#undef ftell
-#undef fseek
-#define ftell(A) ftello(A)
-#define fseek(A,B,C) fseeko((A),(B),(C))
-#endif
-
-/*
- Read a chunk of bytes from a FILE
-
- SYNOPSIS
- my_fread()
- stream File descriptor
- Buffer Buffer to read to
- Count Number of bytes to read
- MyFlags Flags on what to do on error
-
- RETURN
- (size_t) -1 Error
- # Number of bytes read
- */
-
-size_t my_fread(FILE *stream, uchar *Buffer, size_t Count, myf MyFlags)
-{
- size_t readbytes;
- DBUG_ENTER("my_fread");
- DBUG_PRINT("my",("stream: 0x%lx Buffer: 0x%lx Count: %u MyFlags: %d",
- (long) stream, (long) Buffer, (uint) Count, MyFlags));
-
- if ((readbytes= fread(Buffer, sizeof(char), Count, stream)) != Count)
- {
- DBUG_PRINT("error",("Read only %d bytes", (int) readbytes));
- if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
- {
- if (ferror(stream))
- my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
- my_filename(my_fileno(stream)),errno);
- else
- if (MyFlags & (MY_NABP | MY_FNABP))
- my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
- my_filename(my_fileno(stream)),errno);
- }
- my_errno=errno ? errno : -1;
- if (ferror(stream) || MyFlags & (MY_NABP | MY_FNABP))
- DBUG_RETURN((size_t) -1); /* Return with error */
- }
- if (MyFlags & (MY_NABP | MY_FNABP))
- DBUG_RETURN(0); /* Read ok */
- DBUG_RETURN(readbytes);
-} /* my_fread */
-
-
-/*
- Write a chunk of bytes to a stream
-
- my_fwrite()
- stream File descriptor
- Buffer Buffer to write from
- Count Number of bytes to write
- MyFlags Flags on what to do on error
-
- RETURN
- (size_t) -1 Error
- # Number of bytes written
-*/
-
-size_t my_fwrite(FILE *stream, const uchar *Buffer, size_t Count, myf MyFlags)
-{
- size_t writtenbytes =0;
- my_off_t seekptr;
-#if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM)
- uint errors;
-#endif
- DBUG_ENTER("my_fwrite");
- DBUG_PRINT("my",("stream: 0x%lx Buffer: 0x%lx Count: %u MyFlags: %d",
- (long) stream, (long) Buffer, (uint) Count, MyFlags));
-
-#if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM)
- errors=0;
-#endif
- seekptr= ftell(stream);
- for (;;)
- {
- size_t written;
- if ((written = (size_t) fwrite((char*) Buffer,sizeof(char),
- Count, stream)) != Count)
- {
- DBUG_PRINT("error",("Write only %d bytes", (int) writtenbytes));
- my_errno=errno;
- if (written != (size_t) -1)
- {
- seekptr+=written;
- Buffer+=written;
- writtenbytes+=written;
- Count-=written;
- }
-#ifdef EINTR
- if (errno == EINTR)
- {
- (void) my_fseek(stream,seekptr,MY_SEEK_SET,MYF(0));
- continue;
- }
-#endif
-#if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM)
- if (my_thread_var->abort)
- MyFlags&= ~ MY_WAIT_IF_FULL; /* End if aborted by user */
-
- if ((errno == ENOSPC || errno == EDQUOT) &&
- (MyFlags & MY_WAIT_IF_FULL))
- {
- wait_for_free_space("[stream]", errors);
- errors++;
- (void) my_fseek(stream,seekptr,MY_SEEK_SET,MYF(0));
- continue;
- }
-#endif
- if (ferror(stream) || (MyFlags & (MY_NABP | MY_FNABP)))
- {
- if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
- {
- my_error(EE_WRITE, MYF(ME_BELL+ME_WAITTANG),
- my_filename(my_fileno(stream)),errno);
- }
- writtenbytes= (size_t) -1; /* Return that we got error */
- break;
- }
- }
- if (MyFlags & (MY_NABP | MY_FNABP))
- writtenbytes= 0; /* Everything OK */
- else
- writtenbytes+= written;
- break;
- }
- DBUG_RETURN(writtenbytes);
-} /* my_fwrite */
-
-
-/* Seek to position in file */
-
-my_off_t my_fseek(FILE *stream, my_off_t pos, int whence,
- myf MyFlags __attribute__((unused)))
-{
- DBUG_ENTER("my_fseek");
- DBUG_PRINT("my",("stream: 0x%lx pos: %lu whence: %d MyFlags: %d",
- (long) stream, (long) pos, whence, MyFlags));
- DBUG_RETURN(fseek(stream, (off_t) pos, whence) ?
- MY_FILEPOS_ERROR : (my_off_t) ftell(stream));
-} /* my_seek */
-
-
-/* Tell current position of file */
-
-my_off_t my_ftell(FILE *stream, myf MyFlags __attribute__((unused)))
-{
- off_t pos;
- DBUG_ENTER("my_ftell");
- DBUG_PRINT("my",("stream: 0x%lx MyFlags: %d", (long) stream, MyFlags));
- pos=ftell(stream);
- DBUG_PRINT("exit",("ftell: %lu",(ulong) pos));
- DBUG_RETURN((my_off_t) pos);
-} /* my_ftell */
-
-
-/* Get a File corresponding to the stream*/
-int my_fileno(FILE *f)
-{
-#ifdef _WIN32
- return my_win_fileno(f);
-#else
- return fileno(f);
-#endif
-}
diff --git a/dep/mysqllite/mysys/my_gethostbyname.c b/dep/mysqllite/mysys/my_gethostbyname.c
deleted file mode 100644
index 28ecec13ef2..00000000000
--- a/dep/mysqllite/mysys/my_gethostbyname.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Copyright (C) 2002, 2004 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- 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 */
-
-/* Thread safe version of gethostbyname_r() */
-
-#include "mysys_priv.h"
-#if !defined(__WIN__)
-#include <netdb.h>
-#endif
-#include <my_net.h>
-
-/* This file is not needed if my_gethostbyname_r is a macro */
-#if !defined(my_gethostbyname_r)
-
-/*
- Emulate SOLARIS style calls, not because it's better, but just to make the
- usage of getbostbyname_r simpler.
-*/
-
-#if defined(HAVE_GETHOSTBYNAME_R)
-
-#if defined(HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE)
-
-struct hostent *my_gethostbyname_r(const char *name,
- struct hostent *result, char *buffer,
- int buflen, int *h_errnop)
-{
- struct hostent *hp;
- DBUG_ASSERT((size_t) buflen >= sizeof(*result));
- if (gethostbyname_r(name,result, buffer, (size_t) buflen, &hp, h_errnop))
- return 0;
- return hp;
-}
-
-#elif defined(HAVE_GETHOSTBYNAME_R_RETURN_INT)
-
-struct hostent *my_gethostbyname_r(const char *name,
- struct hostent *result, char *buffer,
- int buflen, int *h_errnop)
-{
- if (gethostbyname_r(name,result,(struct hostent_data *) buffer) == -1)
- {
- *h_errnop= errno;
- return 0;
- }
- return result;
-}
-
-#else
-
-/* gethostbyname_r with similar interface as gethostbyname() */
-
-struct hostent *my_gethostbyname_r(const char *name,
- struct hostent *result, char *buffer,
- int buflen, int *h_errnop)
-{
- struct hostent *hp;
- DBUG_ASSERT(buflen >= sizeof(struct hostent_data));
- hp= gethostbyname_r(name,result,(struct hostent_data *) buffer);
- *h_errnop= errno;
- return hp;
-}
-#endif /* GLIBC2_STYLE_GETHOSTBYNAME_R */
-
-#else /* !HAVE_GETHOSTBYNAME_R */
-
-extern mysql_mutex_t LOCK_gethostbyname_r;
-
-/*
- No gethostbyname_r() function exists.
- In this case we have to keep a mutex over the call to ensure that no
- other thread is going to reuse the internal memory.
-
- The user is responsible to call my_gethostbyname_r_free() when he
- is finished with the structure.
-*/
-
-struct hostent *my_gethostbyname_r(const char *name,
- struct hostent *res __attribute__((unused)),
- char *buffer __attribute__((unused)),
- int buflen __attribute__((unused)),
- int *h_errnop)
-{
- struct hostent *hp;
- mysql_mutex_lock(&LOCK_gethostbyname_r);
- hp= gethostbyname(name);
- *h_errnop= h_errno;
- return hp;
-}
-
-void my_gethostbyname_r_free()
-{
- mysql_mutex_unlock(&LOCK_gethostbyname_r);
-}
-
-#endif /* !HAVE_GETHOSTBYNAME_R */
-#endif /* !my_gethostbyname_r */
diff --git a/dep/mysqllite/mysys/my_gethwaddr.c b/dep/mysqllite/mysys/my_gethwaddr.c
deleted file mode 100644
index ab44bac43d3..00000000000
--- a/dep/mysqllite/mysys/my_gethwaddr.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/* Copyright (C) 2004 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 hardware address for an interface */
-/* if there are many available, any non-zero one can be used */
-
-#include "mysys_priv.h"
-#include <m_string.h>
-
-#ifndef MAIN
-
-#ifdef __FreeBSD__
-
-#include <net/ethernet.h>
-#include <sys/sysctl.h>
-#include <net/route.h>
-#include <net/if.h>
-#include <net/if_dl.h>
-
-my_bool my_gethwaddr(uchar *to)
-{
- size_t len;
- char *buf, *next, *end;
- struct if_msghdr *ifm;
- struct sockaddr_dl *sdl;
- int res=1, mib[6]={CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0};
- char zero_array[ETHER_ADDR_LEN] = {0};
-
- if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1)
- goto err;
- if (!(buf = alloca(len)))
- goto err;
- if (sysctl(mib, 6, buf, &len, NULL, 0) < 0)
- goto err;
-
- end = buf + len;
-
- for (next = buf ; res && next < end ; next += ifm->ifm_msglen)
- {
- ifm = (struct if_msghdr *)next;
- if (ifm->ifm_type == RTM_IFINFO)
- {
- sdl= (struct sockaddr_dl *)(ifm + 1);
- memcpy(to, LLADDR(sdl), ETHER_ADDR_LEN);
- res= memcmp(to, zero_array, ETHER_ADDR_LEN) ? 0 : 1;
- }
- }
-
-err:
- return res;
-}
-
-#elif __linux__
-
-#include <net/if.h>
-#include <sys/ioctl.h>
-#include <net/ethernet.h>
-
-my_bool my_gethwaddr(uchar *to)
-{
- int fd, res= 1;
- struct ifreq ifr;
- char zero_array[ETHER_ADDR_LEN] = {0};
-
- fd = socket(AF_INET, SOCK_DGRAM, 0);
- if (fd < 0)
- goto err;
-
- bzero(&ifr, sizeof(ifr));
- strnmov(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name) - 1);
-
- do
- {
- if (ioctl(fd, SIOCGIFHWADDR, &ifr) >= 0)
- {
- memcpy(to, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
- res= memcmp(to, zero_array, ETHER_ADDR_LEN) ? 0 : 1;
- }
- } while (res && (errno == 0 || errno == ENODEV) && ifr.ifr_name[3]++ < '6');
-
- close(fd);
-err:
- return res;
-}
-
-#elif defined(__WIN__)
-
-/*
- Workaround for BUG#32082 (Definition of VOID in my_global.h conflicts with
- windows headers)
-*/
-#ifdef VOID
-#undef VOID
-#define VOID void
-#endif
-
-#include <iphlpapi.h>
-
-/*
- The following typedef is for dynamically loading iphlpapi.dll /
- GetAdaptersAddresses. Dynamic loading is used because
- GetAdaptersAddresses is not available on Windows 2000 which MySQL
- still supports. Static linking would cause an unresolved export.
-*/
-typedef DWORD (WINAPI *pfnGetAdaptersAddresses)(IN ULONG Family,
- IN DWORD Flags,IN PVOID Reserved,
- OUT PIP_ADAPTER_ADDRESSES pAdapterAddresses,
- IN OUT PULONG pOutBufLen);
-
-/*
- my_gethwaddr - Windows version
-
- @brief Retrieve MAC address from network hardware
-
- @param[out] to MAC address exactly six bytes
-
- @return Operation status
- @retval 0 OK
- @retval <>0 FAILED
-*/
-my_bool my_gethwaddr(uchar *to)
-{
- PIP_ADAPTER_ADDRESSES pAdapterAddresses;
- PIP_ADAPTER_ADDRESSES pCurrAddresses;
- IP_ADAPTER_ADDRESSES adapterAddresses;
- ULONG address_len;
- my_bool return_val= 1;
- static pfnGetAdaptersAddresses fnGetAdaptersAddresses=
- (pfnGetAdaptersAddresses)-1;
-
- if(fnGetAdaptersAddresses == (pfnGetAdaptersAddresses)-1)
- {
- /* Get the function from the DLL */
- fnGetAdaptersAddresses= (pfnGetAdaptersAddresses)
- GetProcAddress(LoadLibrary("iphlpapi.dll"),
- "GetAdaptersAddresses");
- }
- if (!fnGetAdaptersAddresses)
- return 1; /* failed to get function */
- address_len= sizeof (IP_ADAPTER_ADDRESSES);
-
- /* Get the required size for the address data. */
- if (fnGetAdaptersAddresses(AF_UNSPEC, 0, 0, &adapterAddresses, &address_len)
- == ERROR_BUFFER_OVERFLOW)
- {
- pAdapterAddresses= my_malloc(address_len, 0);
- if (!pAdapterAddresses)
- return 1; /* error, alloc failed */
- }
- else
- pAdapterAddresses= &adapterAddresses; /* one is enough don't alloc */
-
- /* Get the hardware info. */
- if (fnGetAdaptersAddresses(AF_UNSPEC, 0, 0, pAdapterAddresses, &address_len)
- == NO_ERROR)
- {
- pCurrAddresses= pAdapterAddresses;
-
- while (pCurrAddresses)
- {
- /* Look for ethernet cards. */
- if (pCurrAddresses->IfType == IF_TYPE_ETHERNET_CSMACD)
- {
- /* check for a good address */
- if (pCurrAddresses->PhysicalAddressLength < 6)
- continue; /* bad address */
-
- /* save 6 bytes of the address in the 'to' parameter */
- memcpy(to, pCurrAddresses->PhysicalAddress, 6);
-
- /* Network card found, we're done. */
- return_val= 0;
- break;
- }
- pCurrAddresses= pCurrAddresses->Next;
- }
- }
-
- /* Clean up memory allocation. */
- if (pAdapterAddresses != &adapterAddresses)
- my_free(pAdapterAddresses);
-
- return return_val;
-}
-
-#else /* __FreeBSD__ || __linux__ || __WIN__ */
-/* just fail */
-my_bool my_gethwaddr(uchar *to __attribute__((unused)))
-{
- return 1;
-}
-#endif
-
-#else /* MAIN */
-int main(int argc __attribute__((unused)),char **argv)
-{
- uchar mac[6];
- uint i;
- MY_INIT(argv[0]);
- if (my_gethwaddr(mac))
- {
- printf("my_gethwaddr failed with errno %d\n", errno);
- exit(1);
- }
- for (i=0; i < sizeof(mac); i++)
- {
- if (i) printf(":");
- printf("%02x", mac[i]);
- }
- printf("\n");
- return 0;
-}
-#endif
-
diff --git a/dep/mysqllite/mysys/my_getncpus.c b/dep/mysqllite/mysys/my_getncpus.c
deleted file mode 100644
index 5be961e3bc9..00000000000
--- a/dep/mysqllite/mysys/my_getncpus.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Copyright (C) 2006 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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"
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-static int ncpus=0;
-
-int my_getncpus()
-{
- if (!ncpus)
- {
-#ifdef _SC_NPROCESSORS_ONLN
- ncpus= sysconf(_SC_NPROCESSORS_ONLN);
-#elif defined(__WIN__)
- SYSTEM_INFO sysinfo;
-
- /*
- * We are not calling GetNativeSystemInfo here because (1) we
- * don't believe that they return different values for number
- * of processors and (2) if WOW64 limits processors for Win32
- * then we don't want to try to override that.
- */
- GetSystemInfo(&sysinfo);
-
- ncpus= sysinfo.dwNumberOfProcessors;
-#else
-/* unknown so play safe: assume SMP and forbid uniprocessor build */
- ncpus= 2;
-#endif
- }
- return ncpus;
-}
diff --git a/dep/mysqllite/mysys/my_getopt.c b/dep/mysqllite/mysys/my_getopt.c
deleted file mode 100644
index 51c45ff1309..00000000000
--- a/dep/mysqllite/mysys/my_getopt.c
+++ /dev/null
@@ -1,1419 +0,0 @@
-/* Copyright (C) 2002-2006 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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>
-#include <stdlib.h>
-#include <my_sys.h>
-#include <mysys_err.h>
-#include <my_getopt.h>
-#include <errno.h>
-#include <m_string.h>
-
-typedef void (*init_func_p)(const struct my_option *option, void *variable,
- longlong value);
-
-static void default_reporter(enum loglevel level, const char *format, ...);
-my_error_reporter my_getopt_error_reporter= &default_reporter;
-
-static int findopt(char *, uint, const struct my_option **, const char **);
-my_bool getopt_compare_strings(const char *, const char *, uint);
-static longlong getopt_ll(char *arg, const struct my_option *optp, int *err);
-static ulonglong getopt_ull(char *, const struct my_option *, int *);
-static double getopt_double(char *arg, const struct my_option *optp, int *err);
-static void init_variables(const struct my_option *, init_func_p);
-static void init_one_value(const struct my_option *, void *, longlong);
-static void fini_one_value(const struct my_option *, void *, longlong);
-static int setval(const struct my_option *, void *, char *, my_bool);
-static char *check_struct_option(char *cur_arg, char *key_name);
-
-/*
- The following three variables belong to same group and the number and
- order of their arguments must correspond to each other.
-*/
-static const char *special_opt_prefix[]=
-{"skip", "disable", "enable", "maximum", "loose", 0};
-static const uint special_opt_prefix_lengths[]=
-{ 4, 7, 6, 7, 5, 0};
-enum enum_special_opt
-{ OPT_SKIP, OPT_DISABLE, OPT_ENABLE, OPT_MAXIMUM, OPT_LOOSE};
-
-char *disabled_my_option= (char*) "0";
-char *enabled_my_option= (char*) "1";
-
-/*
- This is a flag that can be set in client programs. 0 means that
- my_getopt will not print error messages, but the client should do
- it by itself
-*/
-
-my_bool my_getopt_print_errors= 1;
-
-/*
- This is a flag that can be set in client programs. 1 means that
- my_getopt will skip over options it does not know how to handle.
-*/
-
-my_bool my_getopt_skip_unknown= 0;
-
-static void default_reporter(enum loglevel level,
- const char *format, ...)
-{
- va_list args;
- va_start(args, format);
- if (level == WARNING_LEVEL)
- fprintf(stderr, "%s", "Warning: ");
- else if (level == INFORMATION_LEVEL)
- fprintf(stderr, "%s", "Info: ");
- vfprintf(stderr, format, args);
- va_end(args);
- fputc('\n', stderr);
- fflush(stderr);
-}
-
-static my_getopt_value getopt_get_addr;
-
-void my_getopt_register_get_addr(my_getopt_value func_addr)
-{
- getopt_get_addr= func_addr;
-}
-
-/**
- Handle command line options.
- Sort options.
- Put options first, until special end of options (--),
- or until the end of argv. Parse options, check that the given option
- matches with one of the options in struct 'my_option'.
- Check that option was given an argument if it requires one
- Call the optional 'get_one_option()' function once for each option.
-
- Note that handle_options() can be invoked multiple times to
- parse a command line in several steps.
- In this case, use the global flag @c my_getopt_skip_unknown to indicate
- that options unknown in the current step should be preserved in the
- command line for later parsing in subsequent steps.
-
- For 'long' options (--a_long_option), @c my_getopt_skip_unknown is
- fully supported. Command line parameters such as:
- - "--a_long_option"
- - "--a_long_option=value"
- - "--a_long_option value"
- will be preserved as is when the option is not known.
-
- For 'short' options (-S), support for @c my_getopt_skip_unknown
- comes with some limitation, because several short options
- can also be specified together in the same command line argument,
- as in "-XYZ".
-
- The first use case supported is: all short options are declared.
- handle_options() will be able to interpret "-XYZ" as one of:
- - an unknown X option
- - "-X -Y -Z", three short options with no arguments
- - "-X -YZ", where Y is a short option with argument Z
- - "-XYZ", where X is a short option with argument YZ
- based on the full short options specifications.
-
- The second use case supported is: no short option is declared.
- handle_options() will reject "-XYZ" as unknown, to be parsed later.
-
- The use case that is explicitly not supported is to provide
- only a partial list of short options to handle_options().
- This function can not be expected to extract some option Y
- in the middle of the string "-XYZ" in these conditions,
- without knowing if X will be declared an option later.
-
- Note that this limitation only impacts parsing of several
- short options from the same command line argument,
- as in "mysqld -anW5".
- When each short option is properly separated out in the command line
- argument, for example in "mysqld -a -n -w5", the code would actually
- work even with partial options specs given at each stage.
-
- @param [in, out] argc command line options (count)
- @param [in, out] argv command line options (values)
- @param [in] longopts descriptor of all valid options
- @param [in] get_one_option optional callback function to process each option,
- can be NULL.
- @return error in case of ambiguous or unknown options,
- 0 on success.
-*/
-int handle_options(int *argc, char ***argv,
- const struct my_option *longopts,
- my_get_one_option get_one_option)
-{
- uint UNINIT_VAR(opt_found), argvpos= 0, length;
- my_bool end_of_options= 0, must_be_var, set_maximum_value,
- option_is_loose;
- char **pos, **pos_end, *optend, *opt_str, key_name[FN_REFLEN];
- const char *UNINIT_VAR(prev_found);
- const struct my_option *optp;
- void *value;
- int error, i;
- my_bool is_cmdline_arg= 1;
-
- /* handle_options() assumes arg0 (program name) always exists */
- DBUG_ASSERT(argc && *argc >= 1);
- DBUG_ASSERT(argv && *argv);
- (*argc)--; /* Skip the program name */
- (*argv)++; /* --- || ---- */
- init_variables(longopts, init_one_value);
-
- /*
- Search for args_separator, if found, then the first part of the
- arguments are loaded from configs
- */
- for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
- {
- if (*pos == args_separator)
- {
- is_cmdline_arg= 0;
- break;
- }
- }
-
- for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)
- {
- char **first= pos;
- char *cur_arg= *pos;
- opt_found= 0;
- if (!is_cmdline_arg && (cur_arg == args_separator))
- {
- is_cmdline_arg= 1;
-
- /* save the separator too if skip unkown options */
- if (my_getopt_skip_unknown)
- (*argv)[argvpos++]= cur_arg;
- else
- (*argc)--;
- continue;
- }
- if (cur_arg[0] == '-' && cur_arg[1] && !end_of_options) /* must be opt */
- {
- char *argument= 0;
- must_be_var= 0;
- set_maximum_value= 0;
- option_is_loose= 0;
-
- cur_arg++; /* skip '-' */
- if (*cur_arg == '-') /* check for long option, */
- {
- if (!*++cur_arg) /* skip the double dash */
- {
- /* '--' means end of options, look no further */
- end_of_options= 1;
- (*argc)--;
- continue;
- }
- opt_str= check_struct_option(cur_arg, key_name);
- optend= strcend(opt_str, '=');
- length= (uint) (optend - opt_str);
- if (*optend == '=')
- optend++;
- else
- optend= 0;
-
- /*
- Find first the right option. Return error in case of an ambiguous,
- or unknown option
- */
- optp= longopts;
- if (!(opt_found= findopt(opt_str, length, &optp, &prev_found)))
- {
- /*
- Didn't find any matching option. Let's see if someone called
- option with a special option prefix
- */
- if (!must_be_var)
- {
- if (optend)
- must_be_var= 1; /* option is followed by an argument */
- for (i= 0; special_opt_prefix[i]; i++)
- {
- if (!getopt_compare_strings(special_opt_prefix[i], opt_str,
- special_opt_prefix_lengths[i]) &&
- (opt_str[special_opt_prefix_lengths[i]] == '-' ||
- opt_str[special_opt_prefix_lengths[i]] == '_'))
- {
- /*
- We were called with a special prefix, we can reuse opt_found
- */
- opt_str+= special_opt_prefix_lengths[i] + 1;
- length-= special_opt_prefix_lengths[i] + 1;
- if (i == OPT_LOOSE)
- option_is_loose= 1;
- if ((opt_found= findopt(opt_str, length, &optp, &prev_found)))
- {
- if (opt_found > 1)
- {
- if (my_getopt_print_errors)
- my_getopt_error_reporter(ERROR_LEVEL,
- "%s: ambiguous option '--%s-%s' (--%s-%s)",
- my_progname, special_opt_prefix[i],
- opt_str, special_opt_prefix[i],
- prev_found);
- return EXIT_AMBIGUOUS_OPTION;
- }
- switch (i) {
- case OPT_SKIP:
- case OPT_DISABLE: /* fall through */
- /*
- double negation is actually enable again,
- for example: --skip-option=0 -> option = TRUE
- */
- optend= (optend && *optend == '0' && !(*(optend + 1))) ?
- enabled_my_option : disabled_my_option;
- break;
- case OPT_ENABLE:
- optend= (optend && *optend == '0' && !(*(optend + 1))) ?
- disabled_my_option : enabled_my_option;
- break;
- case OPT_MAXIMUM:
- set_maximum_value= 1;
- must_be_var= 1;
- break;
- }
- break; /* break from the inner loop, main loop continues */
- }
- i= -1; /* restart the loop */
- }
- }
- }
- if (!opt_found)
- {
- if (my_getopt_skip_unknown)
- {
- /* Preserve all the components of this unknown option. */
- do {
- (*argv)[argvpos++]= *first++;
- } while (first <= pos);
- continue;
- }
- if (must_be_var)
- {
- if (my_getopt_print_errors)
- my_getopt_error_reporter(option_is_loose ?
- WARNING_LEVEL : ERROR_LEVEL,
- "%s: unknown variable '%s'",
- my_progname, cur_arg);
- if (!option_is_loose)
- return EXIT_UNKNOWN_VARIABLE;
- }
- else
- {
- if (my_getopt_print_errors)
- my_getopt_error_reporter(option_is_loose ?
- WARNING_LEVEL : ERROR_LEVEL,
- "%s: unknown option '--%s'",
- my_progname, cur_arg);
- if (!option_is_loose)
- return EXIT_UNKNOWN_OPTION;
- }
- if (option_is_loose)
- {
- (*argc)--;
- continue;
- }
- }
- }
- if (opt_found > 1)
- {
- if (must_be_var)
- {
- if (my_getopt_print_errors)
- my_getopt_error_reporter(ERROR_LEVEL,
- "%s: variable prefix '%s' is not unique",
- my_progname, opt_str);
- return EXIT_VAR_PREFIX_NOT_UNIQUE;
- }
- else
- {
- if (my_getopt_print_errors)
- my_getopt_error_reporter(ERROR_LEVEL,
- "%s: ambiguous option '--%s' (%s, %s)",
- my_progname, opt_str, prev_found,
- optp->name);
- return EXIT_AMBIGUOUS_OPTION;
- }
- }
- if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
- {
- if (my_getopt_print_errors)
- fprintf(stderr,
- "%s: %s: Option '%s' used, but is disabled\n", my_progname,
- option_is_loose ? "WARNING" : "ERROR", opt_str);
- if (option_is_loose)
- {
- (*argc)--;
- continue;
- }
- return EXIT_OPTION_DISABLED;
- }
- error= 0;
- value= optp->var_type & GET_ASK_ADDR ?
- (*getopt_get_addr)(key_name, (uint) strlen(key_name), optp, &error) :
- optp->value;
- if (error)
- return error;
-
- if (optp->arg_type == NO_ARG)
- {
- /*
- Due to historical reasons GET_BOOL var_types still accepts arguments
- despite the NO_ARG arg_type attribute. This can seems a bit unintuitive
- and care should be taken when refactoring this code.
- */
- if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL)
- {
- if (my_getopt_print_errors)
- my_getopt_error_reporter(ERROR_LEVEL,
- "%s: option '--%s' cannot take an argument",
- my_progname, optp->name);
- return EXIT_NO_ARGUMENT_ALLOWED;
- }
- if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
- {
- /*
- Set bool to 1 if no argument or if the user has used
- --enable-'option-name'.
- *optend was set to '0' if one used --disable-option
- */
- (*argc)--;
- if (!optend || *optend == '1' ||
- !my_strcasecmp(&my_charset_latin1, optend, "true"))
- *((my_bool*) value)= (my_bool) 1;
- else if (*optend == '0' ||
- !my_strcasecmp(&my_charset_latin1, optend, "false"))
- *((my_bool*) value)= (my_bool) 0;
- else
- {
- my_getopt_error_reporter(WARNING_LEVEL,
- "%s: ignoring option '--%s' "
- "due to invalid value '%s'",
- my_progname, optp->name, optend);
- continue;
- }
- if (get_one_option && get_one_option(optp->id, optp,
- *((my_bool*) value) ?
- enabled_my_option : disabled_my_option))
- return EXIT_ARGUMENT_INVALID;
- continue;
- }
- argument= optend;
- }
- else if (optp->arg_type == REQUIRED_ARG && !optend)
- {
- /* Check if there are more arguments after this one,
- Note: options loaded from config file that requires value
- should always be in the form '--option=value'.
- */
- if (!is_cmdline_arg || !*++pos)
- {
- if (my_getopt_print_errors)
- my_getopt_error_reporter(ERROR_LEVEL,
- "%s: option '--%s' requires an argument",
- my_progname, optp->name);
- return EXIT_ARGUMENT_REQUIRED;
- }
- argument= *pos;
- (*argc)--;
- }
- else
- argument= optend;
- }
- else /* must be short option */
- {
- for (optend= cur_arg; *optend; optend++)
- {
- opt_found= 0;
- for (optp= longopts; optp->name; optp++)
- {
- if (optp->id && optp->id == (int) (uchar) *optend)
- {
- /* Option recognized. Find next what to do with it */
- opt_found= 1;
- if ((optp->var_type & GET_TYPE_MASK) == GET_DISABLED)
- {
- if (my_getopt_print_errors)
- fprintf(stderr,
- "%s: ERROR: Option '-%c' used, but is disabled\n",
- my_progname, optp->id);
- return EXIT_OPTION_DISABLED;
- }
- if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL &&
- optp->arg_type == NO_ARG)
- {
- *((my_bool*) optp->value)= (my_bool) 1;
- if (get_one_option && get_one_option(optp->id, optp, argument))
- return EXIT_UNSPECIFIED_ERROR;
- continue;
- }
- else if (optp->arg_type == REQUIRED_ARG ||
- optp->arg_type == OPT_ARG)
- {
- if (*(optend + 1))
- {
- /* The rest of the option is option argument */
- argument= optend + 1;
- /* This is in effect a jump out of the outer loop */
- optend= (char*) " ";
- }
- else
- {
- if (optp->arg_type == OPT_ARG)
- {
- if (optp->var_type == GET_BOOL)
- *((my_bool*) optp->value)= (my_bool) 1;
- if (get_one_option && get_one_option(optp->id, optp, argument))
- return EXIT_UNSPECIFIED_ERROR;
- continue;
- }
- /* Check if there are more arguments after this one */
- if (!pos[1])
- {
- if (my_getopt_print_errors)
- my_getopt_error_reporter(ERROR_LEVEL,
- "%s: option '-%c' requires an argument",
- my_progname, optp->id);
- return EXIT_ARGUMENT_REQUIRED;
- }
- argument= *++pos;
- (*argc)--;
- /* the other loop will break, because *optend + 1 == 0 */
- }
- }
- if ((error= setval(optp, optp->value, argument,
- set_maximum_value)))
- return error;
- if (get_one_option && get_one_option(optp->id, optp, argument))
- return EXIT_UNSPECIFIED_ERROR;
- break;
- }
- }
- if (!opt_found)
- {
- if (my_getopt_skip_unknown)
- {
- /*
- We are currently parsing a single argv[] argument
- of the form "-XYZ".
- One or the argument found (say Y) is not an option.
- Hack the string "-XYZ" to make a "-YZ" substring in it,
- and push that to the output as an unrecognized parameter.
- */
- DBUG_ASSERT(optend > *pos);
- DBUG_ASSERT(optend >= cur_arg);
- DBUG_ASSERT(optend <= *pos + strlen(*pos));
- DBUG_ASSERT(*optend);
- optend--;
- optend[0]= '-'; /* replace 'X' or '-' by '-' */
- (*argv)[argvpos++]= optend;
- /*
- Do not continue to parse at the current "-XYZ" argument,
- skip to the next argv[] argument instead.
- */
- optend= (char*) " ";
- }
- else
- {
- if (my_getopt_print_errors)
- my_getopt_error_reporter(ERROR_LEVEL,
- "%s: unknown option '-%c'",
- my_progname, *optend);
- return EXIT_UNKNOWN_OPTION;
- }
- }
- }
- if (opt_found)
- (*argc)--; /* option handled (short), decrease argument count */
- continue;
- }
- if ((error= setval(optp, value, argument, set_maximum_value)))
- return error;
- if (get_one_option && get_one_option(optp->id, optp, argument))
- return EXIT_UNSPECIFIED_ERROR;
-
- (*argc)--; /* option handled (long), decrease argument count */
- }
- else /* non-option found */
- (*argv)[argvpos++]= cur_arg;
- }
- /*
- Destroy the first, already handled option, so that programs that look
- for arguments in 'argv', without checking 'argc', know when to stop.
- Items in argv, before the destroyed one, are all non-option -arguments
- to the program, yet to be (possibly) handled.
- */
- (*argv)[argvpos]= 0;
- return 0;
-}
-
-
-/*
- function: check_struct_option
-
- Arguments: Current argument under processing from argv and a variable
- where to store the possible key name.
-
- Return value: In case option is a struct option, returns a pointer to
- the current argument at the position where the struct option (key_name)
- ends, the next character after the dot. In case argument is not a struct
- option, returns a pointer to the argument.
-
- key_name will hold the name of the key, or 0 if not found.
-*/
-
-static char *check_struct_option(char *cur_arg, char *key_name)
-{
- char *ptr, *end;
-
- ptr= strcend(cur_arg + 1, '.'); /* Skip the first character */
- end= strcend(cur_arg, '=');
-
- /*
- If the first dot is after an equal sign, then it is part
- of a variable value and the option is not a struct option.
- Also, if the last character in the string before the ending
- NULL, or the character right before equal sign is the first
- dot found, the option is not a struct option.
- */
- if (end - ptr > 1)
- {
- uint len= (uint) (ptr - cur_arg);
- set_if_smaller(len, FN_REFLEN-1);
- strmake(key_name, cur_arg, len);
- return ++ptr;
- }
- else
- {
- key_name[0]= 0;
- return cur_arg;
- }
-}
-
-/**
- Parse a boolean command line argument
-
- "ON", "TRUE" and "1" will return true,
- other values will return false.
-
- @param[in] argument The value argument
- @return boolean value
-*/
-static my_bool get_bool_argument(const char *argument)
-{
- if (!my_strcasecmp(&my_charset_latin1, argument, "true") ||
- !my_strcasecmp(&my_charset_latin1, argument, "on"))
- return 1;
- else
- return (my_bool) atoi(argument);
-}
-
-/*
- function: setval
-
- Arguments: opts, argument
- Will set the option value to given value
-*/
-
-static int setval(const struct my_option *opts, void *value, char *argument,
- my_bool set_maximum_value)
-{
- int err= 0, res= 0;
-
- if (!argument)
- argument= enabled_my_option;
-
- if (value)
- {
- if (set_maximum_value && !(value= opts->u_max_value))
- {
- my_getopt_error_reporter(ERROR_LEVEL,
- "%s: Maximum value of '%s' cannot be set",
- my_progname, opts->name);
- return EXIT_NO_PTR_TO_VARIABLE;
- }
-
- switch ((opts->var_type & GET_TYPE_MASK)) {
- case GET_BOOL: /* If argument differs from 0, enable option, else disable */
- *((my_bool*) value)= get_bool_argument(argument);
- break;
- case GET_INT:
- *((int*) value)= (int) getopt_ll(argument, opts, &err);
- break;
- case GET_UINT:
- *((uint*) value)= (uint) getopt_ull(argument, opts, &err);
- break;
- case GET_LONG:
- *((long*) value)= (long) getopt_ll(argument, opts, &err);
- break;
- case GET_ULONG:
- *((long*) value)= (long) getopt_ull(argument, opts, &err);
- break;
- case GET_LL:
- *((longlong*) value)= getopt_ll(argument, opts, &err);
- break;
- case GET_ULL:
- *((ulonglong*) value)= getopt_ull(argument, opts, &err);
- break;
- case GET_DOUBLE:
- *((double*) value)= getopt_double(argument, opts, &err);
- break;
- case GET_STR:
- if (argument == enabled_my_option)
- break; /* string options don't use this default of "1" */
- *((char**) value)= argument;
- break;
- case GET_STR_ALLOC:
- if (argument == enabled_my_option)
- break; /* string options don't use this default of "1" */
- my_free(*((char**) value));
- if (!(*((char**) value)= my_strdup(argument, MYF(MY_WME))))
- {
- res= EXIT_OUT_OF_MEMORY;
- goto ret;
- };
- break;
- case GET_ENUM:
- {
- int type= find_type(argument, opts->typelib, 2);
- if (type == 0)
- {
- /*
- Accept an integer representation of the enumerated item.
- */
- char *endptr;
- ulong arg= strtoul(argument, &endptr, 10);
- if (*endptr || arg >= opts->typelib->count)
- {
- res= EXIT_ARGUMENT_INVALID;
- goto ret;
- }
- *(ulong*)value= arg;
- }
- else
- *(ulong*)value= type - 1;
- }
- break;
- case GET_SET:
- *((ulonglong*)value)= find_typeset(argument, opts->typelib, &err);
- if (err)
- {
- /* Accept an integer representation of the set */
- char *endptr;
- ulonglong arg= (ulonglong) strtol(argument, &endptr, 10);
- if (*endptr || (arg >> 1) >= (1ULL << (opts->typelib->count-1)))
- {
- res= EXIT_ARGUMENT_INVALID;
- goto ret;
- };
- *(ulonglong*)value= arg;
- err= 0;
- }
- break;
- case GET_FLAGSET:
- {
- char *error;
- uint error_len;
-
- *((ulonglong*)value)=
- find_set_from_flags(opts->typelib, opts->typelib->count,
- *(ulonglong *)value, opts->def_value,
- argument, strlen(argument),
- &error, &error_len);
- if (error)
- {
- res= EXIT_ARGUMENT_INVALID;
- goto ret;
- };
- }
- break;
- case GET_NO_ARG: /* get_one_option has taken care of the value already */
- default: /* dummy default to avoid compiler warnings */
- break;
- }
- if (err)
- {
- res= EXIT_UNKNOWN_SUFFIX;
- goto ret;
- };
- }
- return 0;
-
-ret:
- my_getopt_error_reporter(ERROR_LEVEL,
- "%s: Error while setting value '%s' to '%s'",
- my_progname, argument, opts->name);
- return res;
-}
-
-
-/*
- Find option
-
- SYNOPSIS
- findopt()
- optpat Prefix of option to find (with - or _)
- length Length of optpat
- opt_res Options
- ffname Place for pointer to first found name
-
- IMPLEMENTATION
- Go through all options in the my_option struct. Return number
- of options found that match the pattern and in the argument
- list the option found, if any. In case of ambiguous option, store
- the name in ffname argument
-
- RETURN
- 0 No matching options
- # Number of matching options
- ffname points to first matching option
-*/
-
-static int findopt(char *optpat, uint length,
- const struct my_option **opt_res,
- const char **ffname)
-{
- uint count;
- const struct my_option *opt= *opt_res;
-
- for (count= 0; opt->name; opt++)
- {
- if (!getopt_compare_strings(opt->name, optpat, length)) /* match found */
- {
- (*opt_res)= opt;
- if (!opt->name[length]) /* Exact match */
- return 1;
- if (!count)
- {
- /* We only need to know one prev */
- count= 1;
- *ffname= opt->name;
- }
- else if (strcmp(*ffname, opt->name))
- {
- /*
- The above test is to not count same option twice
- (see mysql.cc, option "help")
- */
- count++;
- }
- }
- }
- return count;
-}
-
-
-/*
- function: compare_strings
-
- Works like strncmp, other than 1.) considers '-' and '_' the same.
- 2.) Returns -1 if strings differ, 0 if they are equal
-*/
-
-my_bool getopt_compare_strings(register const char *s, register const char *t,
- uint length)
-{
- char const *end= s + length;
- for (;s != end ; s++, t++)
- {
- if ((*s != '-' ? *s : '_') != (*t != '-' ? *t : '_'))
- return 1;
- }
- return 0;
-}
-
-/*
- function: eval_num_suffix
-
- Transforms a number with a suffix to real number. Suffix can
- be k|K for kilo, m|M for mega or g|G for giga.
-*/
-
-static longlong eval_num_suffix(char *argument, int *error, char *option_name)
-{
- char *endchar;
- longlong num;
-
- *error= 0;
- errno= 0;
- num= strtoll(argument, &endchar, 10);
- if (errno == ERANGE)
- {
- my_getopt_error_reporter(ERROR_LEVEL,
- "Incorrect integer value: '%s'", argument);
- *error= 1;
- return 0;
- }
- if (*endchar == 'k' || *endchar == 'K')
- num*= 1024L;
- else if (*endchar == 'm' || *endchar == 'M')
- num*= 1024L * 1024L;
- else if (*endchar == 'g' || *endchar == 'G')
- num*= 1024L * 1024L * 1024L;
- else if (*endchar)
- {
- fprintf(stderr,
- "Unknown suffix '%c' used for variable '%s' (value '%s')\n",
- *endchar, option_name, argument);
- *error= 1;
- return 0;
- }
- return num;
-}
-
-/*
- function: getopt_ll
-
- Evaluates and returns the value that user gave as an argument
- to a variable. Recognizes (case insensitive) K as KILO, M as MEGA
- and G as GIGA bytes. Some values must be in certain blocks, as
- defined in the given my_option struct, this function will check
- that those values are honored.
- In case of an error, set error value in *err.
-*/
-
-static longlong getopt_ll(char *arg, const struct my_option *optp, int *err)
-{
- longlong num=eval_num_suffix(arg, err, (char*) optp->name);
- return getopt_ll_limit_value(num, optp, NULL);
-}
-
-/*
- function: getopt_ll_limit_value
-
- Applies min/max/block_size to a numeric value of an option.
- Returns "fixed" value.
-*/
-
-longlong getopt_ll_limit_value(longlong num, const struct my_option *optp,
- my_bool *fix)
-{
- longlong old= num;
- my_bool adjusted= FALSE;
- char buf1[255], buf2[255];
- ulonglong block_size= (optp->block_size ? (ulonglong) optp->block_size : 1L);
-
- if (num > 0 && ((ulonglong) num > (ulonglong) optp->max_value) &&
- optp->max_value) /* if max value is not set -> no upper limit */
- {
- num= (ulonglong) optp->max_value;
- adjusted= TRUE;
- }
-
- switch ((optp->var_type & GET_TYPE_MASK)) {
- case GET_INT:
- if (num > (longlong) INT_MAX)
- {
- num= ((longlong) INT_MAX);
- adjusted= TRUE;
- }
- break;
- case GET_LONG:
-#if SIZEOF_LONG < SIZEOF_LONG_LONG
- if (num > (longlong) LONG_MAX)
- {
- num= ((longlong) LONG_MAX);
- adjusted= TRUE;
- }
-#endif
- break;
- default:
- DBUG_ASSERT((optp->var_type & GET_TYPE_MASK) == GET_LL);
- break;
- }
-
- num= (num / block_size);
- num= (longlong) (num * block_size);
-
- if (num < optp->min_value)
- {
- num= optp->min_value;
- if (old < optp->min_value)
- adjusted= TRUE;
- }
-
- if (fix)
- *fix= old != num;
- else if (adjusted)
- my_getopt_error_reporter(WARNING_LEVEL,
- "option '%s': signed value %s adjusted to %s",
- optp->name, llstr(old, buf1), llstr(num, buf2));
- return num;
-}
-
-/*
- function: getopt_ull
-
- This is the same as getopt_ll, but is meant for unsigned long long
- values.
-*/
-
-static ulonglong getopt_ull(char *arg, const struct my_option *optp, int *err)
-{
- ulonglong num= eval_num_suffix(arg, err, (char*) optp->name);
- return getopt_ull_limit_value(num, optp, NULL);
-}
-
-
-ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp,
- my_bool *fix)
-{
- my_bool adjusted= FALSE;
- ulonglong old= num;
- char buf1[255], buf2[255];
-
- if ((ulonglong) num > (ulonglong) optp->max_value &&
- optp->max_value) /* if max value is not set -> no upper limit */
- {
- num= (ulonglong) optp->max_value;
- adjusted= TRUE;
- }
-
- switch ((optp->var_type & GET_TYPE_MASK)) {
- case GET_UINT:
- if (num > (ulonglong) UINT_MAX)
- {
- num= ((ulonglong) UINT_MAX);
- adjusted= TRUE;
- }
- break;
- case GET_ULONG:
-#if SIZEOF_LONG < SIZEOF_LONG_LONG
- if (num > (ulonglong) ULONG_MAX)
- {
- num= ((ulonglong) ULONG_MAX);
- adjusted= TRUE;
- }
-#endif
- break;
- default:
- DBUG_ASSERT((optp->var_type & GET_TYPE_MASK) == GET_ULL);
- break;
- }
-
- if (optp->block_size > 1)
- {
- num/= (ulonglong) optp->block_size;
- num*= (ulonglong) optp->block_size;
- }
-
- if (num < (ulonglong) optp->min_value)
- {
- num= (ulonglong) optp->min_value;
- if (old < (ulonglong) optp->min_value)
- adjusted= TRUE;
- }
-
- if (fix)
- *fix= old != num;
- else if (adjusted)
- my_getopt_error_reporter(WARNING_LEVEL,
- "option '%s': unsigned value %s adjusted to %s",
- optp->name, ullstr(old, buf1), ullstr(num, buf2));
-
- return num;
-}
-
-double getopt_double_limit_value(double num, const struct my_option *optp,
- my_bool *fix)
-{
- my_bool adjusted= FALSE;
- double old= num;
- if (optp->max_value && num > (double) optp->max_value)
- {
- num= (double) optp->max_value;
- adjusted= TRUE;
- }
- if (num < (double) optp->min_value)
- {
- num= (double) optp->min_value;
- adjusted= TRUE;
- }
- if (fix)
- *fix= adjusted;
- else if (adjusted)
- my_getopt_error_reporter(WARNING_LEVEL,
- "option '%s': value %g adjusted to %g",
- optp->name, old, num);
- return num;
-}
-
-/*
- Get double value withing ranges
-
- Evaluates and returns the value that user gave as an argument to a variable.
-
- RETURN
- decimal value of arg
-
- In case of an error, prints an error message and sets *err to
- EXIT_ARGUMENT_INVALID. Otherwise err is not touched
-*/
-
-static double getopt_double(char *arg, const struct my_option *optp, int *err)
-{
- double num;
- int error;
- char *end= arg + 1000; /* Big enough as *arg is \0 terminated */
- num= my_strtod(arg, &end, &error);
- if (end[0] != 0 || error)
- {
- my_getopt_error_reporter(ERROR_LEVEL,
- "Invalid decimal value for option '%s'\n", optp->name);
- *err= EXIT_ARGUMENT_INVALID;
- return 0.0;
- }
- return getopt_double_limit_value(num, optp, NULL);
-}
-
-/*
- Init one value to it's default values
-
- SYNOPSIS
- init_one_value()
- option Option to initialize
- value Pointer to variable
-*/
-
-static void init_one_value(const struct my_option *option, void *variable,
- longlong value)
-{
- DBUG_ENTER("init_one_value");
- switch ((option->var_type & GET_TYPE_MASK)) {
- case GET_BOOL:
- *((my_bool*) variable)= (my_bool) value;
- break;
- case GET_INT:
- *((int*) variable)= (int) getopt_ll_limit_value((int) value, option, NULL);
- break;
- case GET_ENUM:
- *((ulong*) variable)= (ulong) value;
- break;
- case GET_UINT:
- *((uint*) variable)= (uint) getopt_ull_limit_value((uint) value, option, NULL);
- break;
- case GET_LONG:
- *((long*) variable)= (long) getopt_ll_limit_value((long) value, option, NULL);
- break;
- case GET_ULONG:
- *((ulong*) variable)= (ulong) getopt_ull_limit_value((ulong) value, option, NULL);
- break;
- case GET_LL:
- *((longlong*) variable)= (longlong) getopt_ll_limit_value((longlong) value, option, NULL);
- break;
- case GET_ULL:
- *((ulonglong*) variable)= (ulonglong) getopt_ull_limit_value((ulonglong) value, option, NULL);
- break;
- case GET_SET:
- case GET_FLAGSET:
- *((ulonglong*) variable)= (ulonglong) value;
- break;
- case GET_DOUBLE:
- *((double*) variable)= ulonglong2double(value);
- break;
- case GET_STR:
- /*
- Do not clear variable value if it has no default value.
- The default value may already be set.
- NOTE: To avoid compiler warnings, we first cast longlong to intptr,
- so that the value has the same size as a pointer.
- */
- if ((char*) (intptr) value)
- *((char**) variable)= (char*) (intptr) value;
- break;
- case GET_STR_ALLOC:
- /*
- Do not clear variable value if it has no default value.
- The default value may already be set.
- NOTE: To avoid compiler warnings, we first cast longlong to intptr,
- so that the value has the same size as a pointer.
- */
- if ((char*) (intptr) value)
- {
- char **pstr= (char **) variable;
- my_free(*pstr);
- *pstr= my_strdup((char*) (intptr) value, MYF(MY_WME));
- }
- break;
- default: /* dummy default to avoid compiler warnings */
- break;
- }
- DBUG_VOID_RETURN;
-}
-
-
-/*
- Init one value to it's default values
-
- SYNOPSIS
- init_one_value()
- option Option to initialize
- value Pointer to variable
-*/
-
-static void fini_one_value(const struct my_option *option, void *variable,
- longlong value __attribute__ ((unused)))
-{
- DBUG_ENTER("fini_one_value");
- switch ((option->var_type & GET_TYPE_MASK)) {
- case GET_STR_ALLOC:
- my_free(*((char**) variable));
- *((char**) variable)= NULL;
- break;
- default: /* dummy default to avoid compiler warnings */
- break;
- }
- DBUG_VOID_RETURN;
-}
-
-
-void my_cleanup_options(const struct my_option *options)
-{
- init_variables(options, fini_one_value);
-}
-
-
-/*
- initialize all variables to their default values
-
- SYNOPSIS
- init_variables()
- options Array of options
-
- NOTES
- We will initialize the value that is pointed to by options->value.
- If the value is of type GET_ASK_ADDR, we will ask for the address
- for a value and initialize.
-*/
-
-static void init_variables(const struct my_option *options,
- init_func_p init_one_value)
-{
- DBUG_ENTER("init_variables");
- for (; options->name; options++)
- {
- void *value;
- DBUG_PRINT("options", ("name: '%s'", options->name));
- /*
- We must set u_max_value first as for some variables
- options->u_max_value == options->value and in this case we want to
- set the value to default value.
- */
- if (options->u_max_value)
- init_one_value(options, options->u_max_value, options->max_value);
- value= (options->var_type & GET_ASK_ADDR ?
- (*getopt_get_addr)("", 0, options, 0) : options->value);
- if (value)
- init_one_value(options, value, options->def_value);
- }
- DBUG_VOID_RETURN;
-}
-
-/** Prints variable or option name, replacing _ with - */
-static uint print_name(const struct my_option *optp)
-{
- const char *s= optp->name;
- for (;*s;s++)
- putchar(*s == '_' ? '-' : *s);
- return s - optp->name;
-}
-
-/*
- function: my_print_options
-
- Print help for all options and variables.
-*/
-
-void my_print_help(const struct my_option *options)
-{
- uint col, name_space= 22, comment_space= 57;
- const char *line_end;
- const struct my_option *optp;
-
- for (optp= options; optp->name; optp++)
- {
- if (optp->id && optp->id < 256)
- {
- printf(" -%c%s", optp->id, strlen(optp->name) ? ", " : " ");
- col= 6;
- }
- else
- {
- printf(" ");
- col= 2;
- }
- if (strlen(optp->name))
- {
- printf("--");
- col+= 2 + print_name(optp);
- if (optp->arg_type == NO_ARG ||
- (optp->var_type & GET_TYPE_MASK) == GET_BOOL)
- {
- putchar(' ');
- col++;
- }
- else if ((optp->var_type & GET_TYPE_MASK) == GET_STR ||
- (optp->var_type & GET_TYPE_MASK) == GET_STR_ALLOC ||
- (optp->var_type & GET_TYPE_MASK) == GET_ENUM ||
- (optp->var_type & GET_TYPE_MASK) == GET_SET ||
- (optp->var_type & GET_TYPE_MASK) == GET_FLAGSET )
- {
- printf("%s=name%s ", optp->arg_type == OPT_ARG ? "[" : "",
- optp->arg_type == OPT_ARG ? "]" : "");
- col+= (optp->arg_type == OPT_ARG) ? 8 : 6;
- }
- else
- {
- printf("%s=#%s ", optp->arg_type == OPT_ARG ? "[" : "",
- optp->arg_type == OPT_ARG ? "]" : "");
- col+= (optp->arg_type == OPT_ARG) ? 5 : 3;
- }
- if (col > name_space && optp->comment && *optp->comment)
- {
- putchar('\n');
- col= 0;
- }
- }
- for (; col < name_space; col++)
- putchar(' ');
- if (optp->comment && *optp->comment)
- {
- const char *comment= optp->comment, *end= strend(comment);
-
- while ((uint) (end - comment) > comment_space)
- {
- for (line_end= comment + comment_space; *line_end != ' '; line_end--);
- for (; comment != line_end; comment++)
- putchar(*comment);
- comment++; /* skip the space, as a newline will take it's place now */
- putchar('\n');
- for (col= 0; col < name_space; col++)
- putchar(' ');
- }
- printf("%s", comment);
- }
- putchar('\n');
- if ((optp->var_type & GET_TYPE_MASK) == GET_BOOL)
- {
- if (optp->def_value != 0)
- {
- printf("%*s(Defaults to on; use --skip-", name_space, "");
- print_name(optp);
- printf(" to disable.)\n");
- }
- }
- }
-}
-
-
-/*
- function: my_print_options
-
- Print variables.
-*/
-
-void my_print_variables(const struct my_option *options)
-{
- uint name_space= 34, length, nr;
- ulonglong llvalue;
- char buff[255];
- const struct my_option *optp;
-
- for (optp= options; optp->name; optp++)
- {
- length= strlen(optp->name)+1;
- if (length > name_space)
- name_space= length;
- }
-
- printf("\nVariables (--variable-name=value)\n");
- printf("%-*s%s", name_space, "and boolean options {FALSE|TRUE}",
- "Value (after reading options)\n");
- for (length=1; length < 75; length++)
- putchar(length == name_space ? ' ' : '-');
- putchar('\n');
-
- for (optp= options; optp->name; optp++)
- {
- void *value= (optp->var_type & GET_ASK_ADDR ?
- (*getopt_get_addr)("", 0, optp, 0) : optp->value);
- if (value)
- {
- length= print_name(optp);
- for (; length < name_space; length++)
- putchar(' ');
- switch ((optp->var_type & GET_TYPE_MASK)) {
- case GET_SET:
- if (!(llvalue= *(ulonglong*) value))
- printf("%s\n", "");
- else
- for (nr= 0; llvalue && nr < optp->typelib->count; nr++, llvalue >>=1)
- {
- if (llvalue & 1)
- printf( llvalue > 1 ? "%s," : "%s\n", get_type(optp->typelib, nr));
- }
- break;
- case GET_FLAGSET:
- llvalue= *(ulonglong*) value;
- for (nr= 0; llvalue && nr < optp->typelib->count; nr++, llvalue >>=1)
- {
- printf("%s%s=", (nr ? "," : ""), get_type(optp->typelib, nr));
- printf(llvalue & 1 ? "on" : "off");
- }
- printf("\n");
- break;
- case GET_ENUM:
- printf("%s\n", get_type(optp->typelib, *(ulong*) value));
- break;
- case GET_STR:
- case GET_STR_ALLOC: /* fall through */
- printf("%s\n", *((char**) value) ? *((char**) value) :
- "(No default value)");
- break;
- case GET_BOOL:
- printf("%s\n", *((my_bool*) value) ? "TRUE" : "FALSE");
- break;
- case GET_INT:
- printf("%d\n", *((int*) value));
- break;
- case GET_UINT:
- printf("%d\n", *((uint*) value));
- break;
- case GET_LONG:
- printf("%ld\n", *((long*) value));
- break;
- case GET_ULONG:
- printf("%lu\n", *((ulong*) value));
- break;
- case GET_LL:
- printf("%s\n", llstr(*((longlong*) value), buff));
- break;
- case GET_ULL:
- longlong2str(*((ulonglong*) value), buff, 10);
- printf("%s\n", buff);
- break;
- case GET_DOUBLE:
- printf("%g\n", *(double*) value);
- break;
- case GET_NO_ARG:
- printf("(No default value)\n");
- break;
- default:
- printf("(Disabled)\n");
- break;
- }
- }
- }
-}
diff --git a/dep/mysqllite/mysys/my_getpagesize.c b/dep/mysqllite/mysys/my_getpagesize.c
deleted file mode 100644
index b0560cede35..00000000000
--- a/dep/mysqllite/mysys/my_getpagesize.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Copyright (C) 2000-2003 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"
-
-#ifndef HAVE_GETPAGESIZE
-
-#if defined __WIN__
-
-int my_getpagesize(void)
-{
- SYSTEM_INFO si;
- GetSystemInfo(&si);
- return si.dwPageSize;
-}
-
-#else
-
-/* Default implementation */
-int my_getpagesize(void)
-{
- return (int)8192;
-}
-
-#endif
-
-#endif
-
diff --git a/dep/mysqllite/mysys/my_getsystime.c b/dep/mysqllite/mysys/my_getsystime.c
deleted file mode 100644
index 614f49fc425..00000000000
--- a/dep/mysqllite/mysys/my_getsystime.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/* Copyright (C) 2004 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 time since epoc in 100 nanosec units */
-/* thus to get the current time we should use the system function
- with the highest possible resolution */
-
-/*
- TODO: in functions my_micro_time() and my_micro_time_and_time() there
- exists some common code that should be merged into a function.
-*/
-
-#include "mysys_priv.h"
-#include "my_static.h"
-
-ulonglong my_getsystime()
-{
-#ifdef HAVE_CLOCK_GETTIME
- struct timespec tp;
- clock_gettime(CLOCK_REALTIME, &tp);
- return (ulonglong)tp.tv_sec*10000000+(ulonglong)tp.tv_nsec/100;
-#elif defined(__WIN__)
- LARGE_INTEGER t_cnt;
- if (query_performance_frequency)
- {
- QueryPerformanceCounter(&t_cnt);
- return ((t_cnt.QuadPart / query_performance_frequency * 10000000) +
- ((t_cnt.QuadPart % query_performance_frequency) * 10000000 /
- query_performance_frequency) + query_performance_offset);
- }
- return 0;
-#else
- /* TODO: check for other possibilities for hi-res timestamping */
- struct timeval tv;
- gettimeofday(&tv,NULL);
- return (ulonglong)tv.tv_sec*10000000+(ulonglong)tv.tv_usec*10;
-#endif
-}
-
-
-/*
- Return current time
-
- SYNOPSIS
- my_time()
- flags If MY_WME is set, write error if time call fails
-
-*/
-
-time_t my_time(myf flags __attribute__((unused)))
-{
- time_t t;
-#ifdef HAVE_GETHRTIME
- (void) my_micro_time_and_time(&t);
- return t;
-#else
- /* The following loop is here beacuse time() may fail on some systems */
- while ((t= time(0)) == (time_t) -1)
- {
- if (flags & MY_WME)
- fprintf(stderr, "%s: Warning: time() call failed\n", my_progname);
- }
- return t;
-#endif
-}
-
-
-/*
- Return time in micro seconds
-
- SYNOPSIS
- my_micro_time()
-
- NOTES
- This function is to be used to measure performance in micro seconds.
- As it's not defined whats the start time for the clock, this function
- us only useful to measure time between two moments.
-
- For windows platforms we need the frequency value of the CUP. This is
- initalized in my_init.c through QueryPerformanceFrequency().
-
- If Windows platform doesn't support QueryPerformanceFrequency() we will
- obtain the time via GetClockCount, which only supports milliseconds.
-
- RETURN
- Value in microseconds from some undefined point in time
-*/
-
-ulonglong my_micro_time()
-{
-#if defined(__WIN__)
- ulonglong newtime;
- GetSystemTimeAsFileTime((FILETIME*)&newtime);
- return (newtime/10);
-#elif defined(HAVE_GETHRTIME)
- return gethrtime()/1000;
-#else
- ulonglong newtime;
- struct timeval t;
- /*
- The following loop is here because gettimeofday may fail on some systems
- */
- while (gettimeofday(&t, NULL) != 0)
- {}
- newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec;
- return newtime;
-#endif /* defined(__WIN__) */
-}
-
-
-/*
- Return time in seconds and timer in microseconds (not different start!)
-
- SYNOPSIS
- my_micro_time_and_time()
- time_arg Will be set to seconds since epoch (00:00:00 UTC,
- January 1, 1970)
-
- NOTES
- This function is to be useful when we need both the time and microtime.
- For example in MySQL this is used to get the query time start of a query
- and to measure the time of a query (for the slow query log)
-
- IMPLEMENTATION
- Value of time is as in time() call.
- Value of microtime is same as my_micro_time(), which may be totally
- unrealated to time()
-
- RETURN
- Value in microseconds from some undefined point in time
-*/
-
-#define DELTA_FOR_SECONDS 500000000LL /* Half a second */
-
-/* Difference between GetSystemTimeAsFileTime() and now() */
-#define OFFSET_TO_EPOCH 116444736000000000ULL
-
-ulonglong my_micro_time_and_time(time_t *time_arg)
-{
-#if defined(__WIN__)
- ulonglong newtime;
- GetSystemTimeAsFileTime((FILETIME*)&newtime);
- *time_arg= (time_t) ((newtime - OFFSET_TO_EPOCH) / 10000000);
- return (newtime/10);
-#elif defined(HAVE_GETHRTIME)
- /*
- Solaris has a very slow time() call. We optimize this by using the very
- fast gethrtime() call and only calling time() every 1/2 second
- */
- static hrtime_t prev_gethrtime= 0;
- static time_t cur_time= 0;
- hrtime_t cur_gethrtime;
-
- mysql_mutex_lock(&THR_LOCK_time);
- cur_gethrtime= gethrtime();
- /*
- Due to bugs in the Solaris (x86) implementation of gethrtime(),
- the time returned by it might not be monotonic. Don't use the
- cached time(2) value if this is a case.
- */
- if ((prev_gethrtime > cur_gethrtime) ||
- ((cur_gethrtime - prev_gethrtime) > DELTA_FOR_SECONDS))
- {
- cur_time= time(0);
- prev_gethrtime= cur_gethrtime;
- }
- *time_arg= cur_time;
- mysql_mutex_unlock(&THR_LOCK_time);
- return cur_gethrtime/1000;
-#else
- ulonglong newtime;
- struct timeval t;
- /*
- The following loop is here because gettimeofday may fail on some systems
- */
- while (gettimeofday(&t, NULL) != 0)
- {}
- *time_arg= t.tv_sec;
- newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec;
- return newtime;
-#endif /* defined(__WIN__) */
-}
-
-
-/*
- Returns current time
-
- SYNOPSIS
- my_time_possible_from_micro()
- microtime Value from very recent my_micro_time()
-
- NOTES
- This function returns the current time. The microtime argument is only used
- if my_micro_time() uses a function that can safely be converted to the
- current time.
-
- RETURN
- current time
-*/
-
-time_t my_time_possible_from_micro(ulonglong microtime __attribute__((unused)))
-{
-#if defined(__WIN__)
- time_t t;
- while ((t= time(0)) == (time_t) -1)
- {}
- return t;
-#elif defined(HAVE_GETHRTIME)
- return my_time(0); /* Cached time */
-#else
- return (time_t) (microtime / 1000000);
-#endif /* defined(__WIN__) */
-}
-
diff --git a/dep/mysqllite/mysys/my_getwd.c b/dep/mysqllite/mysys/my_getwd.c
deleted file mode 100644
index ace14c8a3c9..00000000000
--- a/dep/mysqllite/mysys/my_getwd.c
+++ /dev/null
@@ -1,167 +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 */
-
-/* my_setwd() and my_getwd() works with intern_filenames !! */
-
-#include "mysys_priv.h"
-#include <m_string.h>
-#include "mysys_err.h"
-#ifdef HAVE_GETWD
-#include <sys/param.h>
-#endif
-#if defined(__WIN__)
-#include <m_ctype.h>
-#include <dos.h>
-#include <direct.h>
-#endif
-
-/* Gets current working directory in buff.
-
- SYNPOSIS
- my_getwd()
- buf Buffer to store result. Can be curr_dir[].
- size Size of buffer
- MyFlags Flags
-
- NOTES
- Directory is allways ended with FN_LIBCHAR
-
- RESULT
- 0 ok
- # error
-*/
-
-int my_getwd(char * buf, size_t size, myf MyFlags)
-{
- char * pos;
- DBUG_ENTER("my_getwd");
- DBUG_PRINT("my",("buf: 0x%lx size: %u MyFlags %d",
- (long) buf, (uint) size, MyFlags));
-
- if (size < 1)
- DBUG_RETURN(-1);
-
- if (curr_dir[0]) /* Current pos is saved here */
- (void) strmake(buf,&curr_dir[0],size-1);
- else
- {
-#if defined(HAVE_GETCWD)
- if (size < 2)
- DBUG_RETURN(-1);
- if (!getcwd(buf,(uint) (size-2)) && MyFlags & MY_WME)
- {
- my_errno=errno;
- my_error(EE_GETWD,MYF(ME_BELL+ME_WAITTANG),errno);
- DBUG_RETURN(-1);
- }
-#elif defined(HAVE_GETWD)
- {
- char pathname[MAXPATHLEN];
- getwd(pathname);
- strmake(buf,pathname,size-1);
- }
-#else
-#error "No way to get current directory"
-#endif
- if (*((pos=strend(buf))-1) != FN_LIBCHAR) /* End with FN_LIBCHAR */
- {
- pos[0]= FN_LIBCHAR;
- pos[1]=0;
- }
- (void) strmake(&curr_dir[0],buf, (size_t) (FN_REFLEN-1));
- }
- DBUG_RETURN(0);
-} /* my_getwd */
-
-
-/* Set new working directory */
-
-int my_setwd(const char *dir, myf MyFlags)
-{
- int res;
- size_t length;
- char *start, *pos;
- DBUG_ENTER("my_setwd");
- DBUG_PRINT("my",("dir: '%s' MyFlags %d", dir, MyFlags));
-
- start=(char *) dir;
- if (! dir[0] || (dir[0] == FN_LIBCHAR && dir[1] == 0))
- dir=FN_ROOTDIR;
- if ((res=chdir((char*) dir)) != 0)
- {
- my_errno=errno;
- if (MyFlags & MY_WME)
- my_error(EE_SETWD,MYF(ME_BELL+ME_WAITTANG),start,errno);
- }
- else
- {
- if (test_if_hard_path(start))
- { /* Hard pathname */
- pos= strmake(&curr_dir[0],start,(size_t) FN_REFLEN-1);
- if (pos[-1] != FN_LIBCHAR)
- {
- length=(uint) (pos-(char*) curr_dir);
- curr_dir[length]=FN_LIBCHAR; /* must end with '/' */
- curr_dir[length+1]='\0';
- }
- }
- else
- curr_dir[0]='\0'; /* Don't save name */
- }
- DBUG_RETURN(res);
-} /* my_setwd */
-
-
-
- /* Test if hard pathname */
- /* Returns 1 if dirname is a hard path */
-
-int test_if_hard_path(register const char *dir_name)
-{
- if (dir_name[0] == FN_HOMELIB && dir_name[1] == FN_LIBCHAR)
- return (home_dir != NullS && test_if_hard_path(home_dir));
- if (dir_name[0] == FN_LIBCHAR)
- return (TRUE);
-#ifdef FN_DEVCHAR
- return (strchr(dir_name,FN_DEVCHAR) != 0);
-#else
- return FALSE;
-#endif
-} /* test_if_hard_path */
-
-
-/*
- Test if a name contains an (absolute or relative) path.
-
- SYNOPSIS
- has_path()
- name The name to test.
-
- RETURN
- TRUE name contains a path.
- FALSE name does not contain a path.
-*/
-
-my_bool has_path(const char *name)
-{
- return test(strchr(name, FN_LIBCHAR))
-#if FN_LIBCHAR != '/'
- || test(strchr(name,'/'))
-#endif
-#ifdef FN_DEVCHAR
- || test(strchr(name, FN_DEVCHAR))
-#endif
- ;
-}
diff --git a/dep/mysqllite/mysys/my_handler.c b/dep/mysqllite/mysys/my_handler.c
deleted file mode 100644
index bd1e313d066..00000000000
--- a/dep/mysqllite/mysys/my_handler.c
+++ /dev/null
@@ -1,604 +0,0 @@
-/* Copyright (C) 2002-2006 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 */
-
-#include <my_global.h>
-#include <m_ctype.h>
-#include <my_base.h>
-#include <my_handler.h>
-#include <my_sys.h>
-
-#include "my_handler_errors.h"
-
-#define CMP_NUM(a,b) (((a) < (b)) ? -1 : ((a) == (b)) ? 0 : 1)
-
-int ha_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length,
- uchar *b, uint b_length, my_bool part_key,
- my_bool skip_end_space)
-{
- if (!part_key)
- return charset_info->coll->strnncollsp(charset_info, a, a_length,
- b, b_length, (my_bool)!skip_end_space);
- return charset_info->coll->strnncoll(charset_info, a, a_length,
- b, b_length, part_key);
-}
-
-
-static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
- my_bool part_key, my_bool skip_end_space)
-{
- uint length= min(a_length,b_length);
- uchar *end= a+ length;
- int flag;
-
- while (a < end)
- if ((flag= (int) *a++ - (int) *b++))
- return flag;
- if (part_key && b_length < a_length)
- return 0;
- if (skip_end_space && a_length != b_length)
- {
- int swap= 1;
- /*
- We are using space compression. We have to check if longer key
- has next character < ' ', in which case it's less than the shorter
- key that has an implicite space afterwards.
-
- This code is identical to the one in
- strings/ctype-simple.c:my_strnncollsp_simple
- */
- if (a_length < b_length)
- {
- /* put shorter key in a */
- a_length= b_length;
- a= b;
- swap= -1; /* swap sign of result */
- }
- for (end= a + a_length-length; a < end ; a++)
- {
- if (*a != ' ')
- return (*a < ' ') ? -swap : swap;
- }
- return 0;
- }
- return (int) (a_length-b_length);
-}
-
-
-/*
- Compare two keys
-
- SYNOPSIS
- ha_key_cmp()
- keyseg Array of key segments of key to compare
- a First key to compare, in format from _mi_pack_key()
- This is normally key specified by user
- b Second key to compare. This is always from a row
- key_length Length of key to compare. This can be shorter than
- a to just compare sub keys
- next_flag How keys should be compared
- If bit SEARCH_FIND is not set the keys includes the row
- position and this should also be compared
- diff_pos OUT Number of first keypart where values differ, counting
- from one.
- diff_pos[1] OUT (b + diff_pos[1]) points to first value in tuple b
- that is different from corresponding value in tuple a.
-
- EXAMPLES
- Example1: if the function is called for tuples
- ('aaa','bbb') and ('eee','fff'), then
- diff_pos[0] = 1 (as 'aaa' != 'eee')
- diff_pos[1] = 0 (offset from beggining of tuple b to 'eee' keypart).
-
- Example2: if the index function is called for tuples
- ('aaa','bbb') and ('aaa','fff'),
- diff_pos[0] = 2 (as 'aaa' != 'eee')
- diff_pos[1] = 3 (offset from beggining of tuple b to 'fff' keypart,
- here we assume that first key part is CHAR(3) NOT NULL)
-
- NOTES
- Number-keys can't be splited
-
- RETURN VALUES
- <0 If a < b
- 0 If a == b
- >0 If a > b
-*/
-
-#define FCMP(A,B) ((int) (A) - (int) (B))
-
-int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
- register uchar *b, uint key_length, uint nextflag,
- uint *diff_pos)
-{
- int flag;
- int16 s_1,s_2;
- int32 l_1,l_2;
- uint32 u_1,u_2;
- float f_1,f_2;
- double d_1,d_2;
- uint next_key_length;
- uchar *orig_b= b;
-
- *diff_pos=0;
- for ( ; (int) key_length >0 ; key_length=next_key_length, keyseg++)
- {
- uchar *end;
- uint piks=! (keyseg->flag & HA_NO_SORT);
- (*diff_pos)++;
- diff_pos[1]= (uint)(b - orig_b);
-
- /* Handle NULL part */
- if (keyseg->null_bit)
- {
- key_length--;
- if (*a != *b && piks)
- {
- flag = (int) *a - (int) *b;
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- }
- b++;
- if (!*a++) /* If key was NULL */
- {
- if (nextflag == (SEARCH_FIND | SEARCH_UPDATE))
- nextflag=SEARCH_SAME; /* Allow duplicate keys */
- else if (nextflag & SEARCH_NULL_ARE_NOT_EQUAL)
- {
- /*
- This is only used from mi_check() to calculate cardinality.
- It can't be used when searching for a key as this would cause
- compare of (a,b) and (b,a) to return the same value.
- */
- return -1;
- }
- next_key_length=key_length;
- continue; /* To next key part */
- }
- }
- end= a+ min(keyseg->length,key_length);
- next_key_length=key_length-keyseg->length;
-
- switch ((enum ha_base_keytype) keyseg->type) {
- case HA_KEYTYPE_TEXT: /* Ascii; Key is converted */
- if (keyseg->flag & HA_SPACE_PACK)
- {
- int a_length,b_length,pack_length;
- get_key_length(a_length,a);
- get_key_pack_length(b_length,pack_length,b);
- next_key_length=key_length-b_length-pack_length;
-
- if (piks &&
- (flag=ha_compare_text(keyseg->charset,a,a_length,b,b_length,
- (my_bool) ((nextflag & SEARCH_PREFIX) &&
- next_key_length <= 0),
- (my_bool)!(nextflag & SEARCH_PREFIX))))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a+=a_length;
- b+=b_length;
- break;
- }
- else
- {
- uint length=(uint) (end-a), a_length=length, b_length=length;
- if (piks &&
- (flag= ha_compare_text(keyseg->charset, a, a_length, b, b_length,
- (my_bool) ((nextflag & SEARCH_PREFIX) &&
- next_key_length <= 0),
- (my_bool)!(nextflag & SEARCH_PREFIX))))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a=end;
- b+=length;
- }
- break;
- case HA_KEYTYPE_BINARY:
- case HA_KEYTYPE_BIT:
- if (keyseg->flag & HA_SPACE_PACK)
- {
- int a_length,b_length,pack_length;
- get_key_length(a_length,a);
- get_key_pack_length(b_length,pack_length,b);
- next_key_length=key_length-b_length-pack_length;
-
- if (piks &&
- (flag=compare_bin(a,a_length,b,b_length,
- (my_bool) ((nextflag & SEARCH_PREFIX) &&
- next_key_length <= 0),1)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a+=a_length;
- b+=b_length;
- break;
- }
- else
- {
- uint length=keyseg->length;
- if (piks &&
- (flag=compare_bin(a,length,b,length,
- (my_bool) ((nextflag & SEARCH_PREFIX) &&
- next_key_length <= 0),0)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a+=length;
- b+=length;
- }
- break;
- case HA_KEYTYPE_VARTEXT1:
- case HA_KEYTYPE_VARTEXT2:
- {
- int a_length,b_length,pack_length;
- get_key_length(a_length,a);
- get_key_pack_length(b_length,pack_length,b);
- next_key_length=key_length-b_length-pack_length;
-
- if (piks &&
- (flag= ha_compare_text(keyseg->charset,a,a_length,b,b_length,
- (my_bool) ((nextflag & SEARCH_PREFIX) &&
- next_key_length <= 0),
- (my_bool) ((nextflag & (SEARCH_FIND |
- SEARCH_UPDATE)) ==
- SEARCH_FIND &&
- ! (keyseg->flag &
- HA_END_SPACE_ARE_EQUAL)))))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a+= a_length;
- b+= b_length;
- break;
- }
- break;
- case HA_KEYTYPE_VARBINARY1:
- case HA_KEYTYPE_VARBINARY2:
- {
- int a_length,b_length,pack_length;
- get_key_length(a_length,a);
- get_key_pack_length(b_length,pack_length,b);
- next_key_length=key_length-b_length-pack_length;
-
- if (piks &&
- (flag=compare_bin(a,a_length,b,b_length,
- (my_bool) ((nextflag & SEARCH_PREFIX) &&
- next_key_length <= 0), 0)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a+=a_length;
- b+=b_length;
- }
- break;
- case HA_KEYTYPE_INT8:
- {
- int i_1= (int) *((signed char*) a);
- int i_2= (int) *((signed char*) b);
- if (piks && (flag = CMP_NUM(i_1,i_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a= end;
- b++;
- break;
- }
- case HA_KEYTYPE_SHORT_INT:
- s_1= mi_sint2korr(a);
- s_2= mi_sint2korr(b);
- if (piks && (flag = CMP_NUM(s_1,s_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a= end;
- b+= 2; /* sizeof(short int); */
- break;
- case HA_KEYTYPE_USHORT_INT:
- {
- uint16 us_1,us_2;
- us_1= mi_sint2korr(a);
- us_2= mi_sint2korr(b);
- if (piks && (flag = CMP_NUM(us_1,us_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a= end;
- b+=2; /* sizeof(short int); */
- break;
- }
- case HA_KEYTYPE_LONG_INT:
- l_1= mi_sint4korr(a);
- l_2= mi_sint4korr(b);
- if (piks && (flag = CMP_NUM(l_1,l_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a= end;
- b+= 4; /* sizeof(long int); */
- break;
- case HA_KEYTYPE_ULONG_INT:
- u_1= mi_sint4korr(a);
- u_2= mi_sint4korr(b);
- if (piks && (flag = CMP_NUM(u_1,u_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a= end;
- b+= 4; /* sizeof(long int); */
- break;
- case HA_KEYTYPE_INT24:
- l_1=mi_sint3korr(a);
- l_2=mi_sint3korr(b);
- if (piks && (flag = CMP_NUM(l_1,l_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a= end;
- b+= 3;
- break;
- case HA_KEYTYPE_UINT24:
- l_1=mi_uint3korr(a);
- l_2=mi_uint3korr(b);
- if (piks && (flag = CMP_NUM(l_1,l_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a= end;
- b+= 3;
- break;
- case HA_KEYTYPE_FLOAT:
- mi_float4get(f_1,a);
- mi_float4get(f_2,b);
- /*
- The following may give a compiler warning about floating point
- comparison not being safe, but this is ok in this context as
- we are bascily doing sorting
- */
- if (piks && (flag = CMP_NUM(f_1,f_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a= end;
- b+= 4; /* sizeof(float); */
- break;
- case HA_KEYTYPE_DOUBLE:
- mi_float8get(d_1,a);
- mi_float8get(d_2,b);
- /*
- The following may give a compiler warning about floating point
- comparison not being safe, but this is ok in this context as
- we are bascily doing sorting
- */
- if (piks && (flag = CMP_NUM(d_1,d_2)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a= end;
- b+= 8; /* sizeof(double); */
- break;
- case HA_KEYTYPE_NUM: /* Numeric key */
- {
- int swap_flag= 0;
- int alength,blength;
-
- if (keyseg->flag & HA_REVERSE_SORT)
- {
- swap_variables(uchar*, a, b);
- swap_flag=1; /* Remember swap of a & b */
- end= a+ (int) (end-b);
- }
- if (keyseg->flag & HA_SPACE_PACK)
- {
- alength= *a++; blength= *b++;
- end=a+alength;
- next_key_length=key_length-blength-1;
- }
- else
- {
- alength= (int) (end-a);
- blength=keyseg->length;
- /* remove pre space from keys */
- for ( ; alength && *a == ' ' ; a++, alength--) ;
- for ( ; blength && *b == ' ' ; b++, blength--) ;
- }
- if (piks)
- {
- if (*a == '-')
- {
- if (*b != '-')
- return -1;
- a++; b++;
- swap_variables(uchar*, a, b);
- swap_variables(int, alength, blength);
- swap_flag=1-swap_flag;
- alength--; blength--;
- end=a+alength;
- }
- else if (*b == '-')
- return 1;
- while (alength && (*a == '+' || *a == '0'))
- {
- a++; alength--;
- }
- while (blength && (*b == '+' || *b == '0'))
- {
- b++; blength--;
- }
- if (alength != blength)
- return (alength < blength) ? -1 : 1;
- while (a < end)
- if (*a++ != *b++)
- return ((int) a[-1] - (int) b[-1]);
- }
- else
- {
- b+=(end-a);
- a=end;
- }
-
- if (swap_flag) /* Restore pointers */
- swap_variables(uchar*, a, b);
- break;
- }
-#ifdef HAVE_LONG_LONG
- case HA_KEYTYPE_LONGLONG:
- {
- longlong ll_a,ll_b;
- ll_a= mi_sint8korr(a);
- ll_b= mi_sint8korr(b);
- if (piks && (flag = CMP_NUM(ll_a,ll_b)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a= end;
- b+= 8;
- break;
- }
- case HA_KEYTYPE_ULONGLONG:
- {
- ulonglong ll_a,ll_b;
- ll_a= mi_uint8korr(a);
- ll_b= mi_uint8korr(b);
- if (piks && (flag = CMP_NUM(ll_a,ll_b)))
- return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
- a= end;
- b+= 8;
- break;
- }
-#endif
- case HA_KEYTYPE_END: /* Ready */
- goto end; /* diff_pos is incremented */
- }
- }
- (*diff_pos)++;
-end:
- if (!(nextflag & SEARCH_FIND))
- {
- uint i;
- if (nextflag & (SEARCH_NO_FIND | SEARCH_LAST)) /* Find record after key */
- return (nextflag & (SEARCH_BIGGER | SEARCH_LAST)) ? -1 : 1;
- flag=0;
- for (i=keyseg->length ; i-- > 0 ; )
- {
- if (*a++ != *b++)
- {
- flag= FCMP(a[-1],b[-1]);
- break;
- }
- }
- if (nextflag & SEARCH_SAME)
- return (flag); /* read same */
- if (nextflag & SEARCH_BIGGER)
- return (flag <= 0 ? -1 : 1); /* read next */
- return (flag < 0 ? -1 : 1); /* read previous */
- }
- return 0;
-} /* ha_key_cmp */
-
-
-/*
- Find the first NULL value in index-suffix values tuple
-
- SYNOPSIS
- ha_find_null()
- keyseg Array of keyparts for key suffix
- a Key suffix value tuple
-
- DESCRIPTION
- Find the first NULL value in index-suffix values tuple.
-
- TODO
- Consider optimizing this function or its use so we don't search for
- NULL values in completely NOT NULL index suffixes.
-
- RETURN
- First key part that has NULL as value in values tuple, or the last key
- part (with keyseg->type==HA_TYPE_END) if values tuple doesn't contain
- NULLs.
-*/
-
-HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a)
-{
- for (; (enum ha_base_keytype) keyseg->type != HA_KEYTYPE_END; keyseg++)
- {
- uchar *end;
- if (keyseg->null_bit)
- {
- if (!*a++)
- return keyseg;
- }
- end= a+ keyseg->length;
-
- switch ((enum ha_base_keytype) keyseg->type) {
- case HA_KEYTYPE_TEXT:
- case HA_KEYTYPE_BINARY:
- case HA_KEYTYPE_BIT:
- if (keyseg->flag & HA_SPACE_PACK)
- {
- int a_length;
- get_key_length(a_length, a);
- a += a_length;
- break;
- }
- else
- a= end;
- break;
- case HA_KEYTYPE_VARTEXT1:
- case HA_KEYTYPE_VARTEXT2:
- case HA_KEYTYPE_VARBINARY1:
- case HA_KEYTYPE_VARBINARY2:
- {
- int a_length;
- get_key_length(a_length, a);
- a+= a_length;
- break;
- }
- case HA_KEYTYPE_NUM:
- if (keyseg->flag & HA_SPACE_PACK)
- {
- int alength= *a++;
- end= a+alength;
- }
- a= end;
- break;
- case HA_KEYTYPE_INT8:
- case HA_KEYTYPE_SHORT_INT:
- case HA_KEYTYPE_USHORT_INT:
- case HA_KEYTYPE_LONG_INT:
- case HA_KEYTYPE_ULONG_INT:
- case HA_KEYTYPE_INT24:
- case HA_KEYTYPE_UINT24:
-#ifdef HAVE_LONG_LONG
- case HA_KEYTYPE_LONGLONG:
- case HA_KEYTYPE_ULONGLONG:
-#endif
- case HA_KEYTYPE_FLOAT:
- case HA_KEYTYPE_DOUBLE:
- a= end;
- break;
- case HA_KEYTYPE_END: /* purecov: inspected */
- /* keep compiler happy */
- DBUG_ASSERT(0);
- break;
- }
- }
- return keyseg;
-}
-
-
-
-/*
- Register handler error messages for usage with my_error()
-
- NOTES
- This is safe to call multiple times as my_error_register()
- will ignore calls to register already registered error numbers.
-*/
-
-static const char **get_handler_error_messages()
-{
- return handler_error_messages;
-}
-
-void my_handler_error_register(void)
-{
- /*
- If you got compilation error here about compile_time_assert array, check
- that every HA_ERR_xxx constant has a corresponding error message in
- handler_error_messages[] list (check mysys/ma_handler_errors.h and
- include/my_base.h).
- */
- compile_time_assert(HA_ERR_FIRST + array_elements(handler_error_messages) ==
- HA_ERR_LAST + 1);
- my_error_register(get_handler_error_messages, HA_ERR_FIRST,
- HA_ERR_FIRST+ array_elements(handler_error_messages)-1);
-}
-
-
-void my_handler_error_unregister(void)
-{
- my_error_unregister(HA_ERR_FIRST,
- HA_ERR_FIRST+ array_elements(handler_error_messages)-1);
-}
diff --git a/dep/mysqllite/mysys/my_handler_errors.h b/dep/mysqllite/mysys/my_handler_errors.h
deleted file mode 100644
index e4e62f47fed..00000000000
--- a/dep/mysqllite/mysys/my_handler_errors.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef MYSYS_MY_HANDLER_ERRORS_INCLUDED
-#define MYSYS_MY_HANDLER_ERRORS_INCLUDED
-
-/*
- Errors a handler can give you
-*/
-
-static const char *handler_error_messages[]=
-{
- "Didn't find key on read or update",
- "Duplicate key on write or update",
- "Internal (unspecified) error in handler",
- "Someone has changed the row since it was read (while the table was locked to prevent it)",
- "Wrong index given to function",
- "Undefined handler error 125",
- "Index file is crashed",
- "Record file is crashed",
- "Out of memory in engine",
- "Undefined handler error 129",
- "Incorrect file format",
- "Command not supported by database",
- "Old database file",
- "No record read before update",
- "Record was already deleted (or record file crashed)",
- "No more room in record file",
- "No more room in index file",
- "No more records (read after end of file)",
- "Unsupported extension used for table",
- "Too big row",
- "Wrong create options",
- "Duplicate unique key or constraint on write or update",
- "Unknown character set used in table",
- "Conflicting table definitions in sub-tables of MERGE table",
- "Table is crashed and last repair failed",
- "Table was marked as crashed and should be repaired",
- "Lock timed out; Retry transaction",
- "Lock table is full; Restart program with a larger locktable",
- "Updates are not allowed under a read only transactions",
- "Lock deadlock; Retry transaction",
- "Foreign key constraint is incorrectly formed",
- "Cannot add a child row",
- "Cannot delete a parent row",
- "No savepoint with that name",
- "Non unique key block size",
- "The table does not exist in engine",
- "The table already existed in storage engine",
- "Could not connect to storage engine",
- "Unexpected null pointer found when using spatial index",
- "The table changed in storage engine",
- "There's no partition in table for the given value",
- "Row-based binlogging of row failed",
- "Index needed in foreign key constraint",
- "Upholding foreign key constraints would lead to a duplicate key error in "
- "some other table",
- "Table needs to be upgraded before it can be used",
- "Table is read only",
- "Failed to get next auto increment value",
- "Failed to set row auto increment value",
- "Unknown (generic) error from engine",
- "Record is the same",
- "It is not possible to log this statement",
- "The event was corrupt, leading to illegal data being read",
- "The table is of a new format not supported by this version",
- "The event could not be processed no other hanlder error happened",
- "Got a fatal error during initialzaction of handler",
- "File to short; Expected more data in file",
- "Read page with wrong checksum",
- "Too many active concurrent transactions"
-};
-
-#endif /* MYSYS_MY_HANDLER_ERRORS_INCLUDED */
diff --git a/dep/mysqllite/mysys/my_init.c b/dep/mysqllite/mysys/my_init.c
deleted file mode 100644
index 9b0939c1c75..00000000000
--- a/dep/mysqllite/mysys/my_init.c
+++ /dev/null
@@ -1,607 +0,0 @@
-/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 "my_static.h"
-#include "mysys_err.h"
-#include <m_string.h>
-#include <m_ctype.h>
-#include <signal.h>
-#ifdef __WIN__
-#ifdef _MSC_VER
-#include <locale.h>
-#include <crtdbg.h>
-/* WSAStartup needs winsock library*/
-#pragma comment(lib, "ws2_32")
-#endif
-my_bool have_tcpip=0;
-static void my_win_init(void);
-static my_bool win32_init_tcp_ip();
-#else
-#define my_win_init()
-#endif
-
-#define SCALE_SEC 100
-#define SCALE_USEC 10000
-
-my_bool my_init_done= 0;
-/** True if @c my_basic_init() has been called. */
-my_bool my_basic_init_done= 0;
-uint mysys_usage_id= 0; /* Incremented for each my_init() */
-ulong my_thread_stack_size= 65536;
-
-static ulong atoi_octal(const char *str)
-{
- long int tmp;
- while (*str && my_isspace(&my_charset_latin1, *str))
- str++;
- str2int(str,
- (*str == '0' ? 8 : 10), /* Octalt or decimalt */
- 0, INT_MAX, &tmp);
- return (ulong) tmp;
-}
-
-MYSQL_FILE *mysql_stdin= NULL;
-static MYSQL_FILE instrumented_stdin;
-
-/**
- Perform a limited initialisation of mysys.
- This initialisation is sufficient to:
- - allocate memory,
- - read configuration files,
- - parse command lines arguments.
- To complete the mysys initialisation,
- call my_init().
- @return 0 on success
-*/
-my_bool my_basic_init(void)
-{
- char * str;
-
- if (my_basic_init_done)
- return 0;
- my_basic_init_done= 1;
-
- mysys_usage_id++;
- my_umask= 0660; /* Default umask for new files */
- my_umask_dir= 0700; /* Default umask for new directories */
-
- /* Default creation of new files */
- if ((str= getenv("UMASK")) != 0)
- my_umask= (int) (atoi_octal(str) | 0600);
- /* Default creation of new dir's */
- if ((str= getenv("UMASK_DIR")) != 0)
- my_umask_dir= (int) (atoi_octal(str) | 0700);
-
- init_glob_errs();
-
- instrumented_stdin.m_file= stdin;
- instrumented_stdin.m_psi= NULL; /* not yet instrumented */
- mysql_stdin= & instrumented_stdin;
-
- if (my_thread_global_init())
- return 1;
-
-#if defined(SAFE_MUTEX)
- safe_mutex_global_init(); /* Must be called early */
-#endif
-
-#if defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX)
- fastmutex_global_init(); /* Must be called early */
-#endif
-
-#if defined(HAVE_PTHREAD_INIT)
- pthread_init(); /* Must be called before DBUG_ENTER */
-#endif
- if (my_thread_basic_global_init())
- return 1;
-
- /* $HOME is needed early to parse configuration files located in ~/ */
- if ((home_dir= getenv("HOME")) != 0)
- home_dir= intern_filename(home_dir_buff, home_dir);
-
- return 0;
-}
-
-
-/*
- Init my_sys functions and my_sys variabels
-
- SYNOPSIS
- my_init()
-
- RETURN
- 0 ok
- 1 Couldn't initialize environment
-*/
-
-my_bool my_init(void)
-{
- if (my_init_done)
- return 0;
-
- my_init_done= 1;
-
- if (my_basic_init())
- return 1;
-
- if (my_thread_global_init())
- return 1;
-
- {
- DBUG_ENTER("my_init");
- DBUG_PROCESS((char*) (my_progname ? my_progname : "unknown"));
- my_win_init();
- DBUG_PRINT("exit", ("home: '%s'", home_dir));
-#ifdef __WIN__
- win32_init_tcp_ip();
-#endif
- DBUG_RETURN(0);
- }
-} /* my_init */
-
-
- /* End my_sys */
-
-void my_end(int infoflag)
-{
- /*
- this code is suboptimal to workaround a bug in
- Sun CC: Sun C++ 5.6 2004/06/02 for x86, and should not be
- optimized until this compiler is not in use anymore
- */
- FILE *info_file= DBUG_FILE;
- my_bool print_info= (info_file != stderr);
-
- if (!my_init_done)
- return;
-
- /*
- 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: infoflag: %d print_info: %d",
- infoflag, print_info));
- if (!info_file)
- {
- info_file= stderr;
- print_info= 0;
- }
-
- if ((infoflag & MY_CHECK_ERROR) || print_info)
-
- { /* Test if some file is left open */
- if (my_file_opened | my_stream_opened)
- {
- char ebuff[512];
- my_snprintf(ebuff, sizeof(ebuff), EE(EE_OPEN_WARNING),
- my_file_opened, my_stream_opened);
- my_message_stderr(EE_OPEN_WARNING, ebuff, ME_BELL);
- DBUG_PRINT("error", ("%s", ebuff));
- my_print_open_files();
- }
- }
- free_charsets();
- my_error_unregister_all();
- my_once_free();
-
- if ((infoflag & MY_GIVE_INFO) || print_info)
- {
-#ifdef HAVE_GETRUSAGE
- struct rusage rus;
-#ifdef HAVE_purify
- /* Purify assumes that rus is uninitialized after getrusage call */
- bzero((char*) &rus, sizeof(rus));
-#endif
- if (!getrusage(RUSAGE_SELF, &rus))
- fprintf(info_file,"\n\
-User time %.2f, System time %.2f\n\
-Maximum resident set size %ld, Integral resident set size %ld\n\
-Non-physical pagefaults %ld, Physical pagefaults %ld, Swaps %ld\n\
-Blocks in %ld out %ld, Messages in %ld out %ld, Signals %ld\n\
-Voluntary context switches %ld, Involuntary context switches %ld\n",
- (rus.ru_utime.tv_sec * SCALE_SEC +
- rus.ru_utime.tv_usec / SCALE_USEC) / 100.0,
- (rus.ru_stime.tv_sec * SCALE_SEC +
- rus.ru_stime.tv_usec / SCALE_USEC) / 100.0,
- rus.ru_maxrss, rus.ru_idrss,
- rus.ru_minflt, rus.ru_majflt,
- rus.ru_nswap, rus.ru_inblock, rus.ru_oublock,
- rus.ru_msgsnd, rus.ru_msgrcv, rus.ru_nsignals,
- rus.ru_nvcsw, rus.ru_nivcsw);
-#endif
-#if defined(__WIN__) && defined(_MSC_VER)
- _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
- _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR );
- _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
- _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
- _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
- _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );
- _CrtCheckMemory();
- _CrtDumpMemoryLeaks();
-#endif
- }
-
- if (!(infoflag & MY_DONT_FREE_DBUG))
- {
- DBUG_END(); /* Must be done before my_thread_end */
- }
-
- my_thread_end();
- my_thread_global_end();
-#if defined(SAFE_MUTEX)
- /*
- 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 | MY_CHECK_ERROR)) ? stderr :
- (FILE *) 0);
-#endif /* defined(SAFE_MUTEX) */
-
-#ifdef __WIN__
- if (have_tcpip)
- WSACleanup();
-#endif /* __WIN__ */
-
- my_init_done=0;
- my_basic_init_done= 0;
-} /* my_end */
-
-
-#ifdef __WIN__
-
-
-/*
- my_parameter_handler
-
- Invalid parameter handler we will use instead of the one "baked"
- into the CRT for MSC v8. This one just prints out what invalid
- parameter was encountered. By providing this routine, routines like
- lseek will return -1 when we expect them to instead of crash.
-*/
-
-void my_parameter_handler(const wchar_t * expression, const wchar_t * function,
- const wchar_t * file, unsigned int line,
- uintptr_t pReserved)
-{
- DBUG_PRINT("my",("Expression: %s function: %s file: %s, line: %d",
- expression, function, file, line));
-}
-
-
-#ifdef __MSVC_RUNTIME_CHECKS
-#include <rtcapi.h>
-
-/* Turn off runtime checks for 'handle_rtc_failure' */
-#pragma runtime_checks("", off)
-
-/*
- handle_rtc_failure
- Catch the RTC error and dump it to stderr
-*/
-
-int handle_rtc_failure(int err_type, const char *file, int line,
- const char* module, const char *format, ...)
-{
- va_list args;
- va_start(args, format);
- fprintf(stderr, "Error:");
- vfprintf(stderr, format, args);
- fprintf(stderr, " At %s:%d\n", file, line);
- va_end(args);
- (void) fflush(stderr);
-
- return 0; /* Error is handled */
-}
-#pragma runtime_checks("", restore)
-#endif
-
-#define OFFSET_TO_EPOC ((__int64) 134774 * 24 * 60 * 60 * 1000 * 1000 * 10)
-#define MS 10000000
-
-static void win_init_time(void)
-{
- /* The following is used by time functions */
- FILETIME ft;
- LARGE_INTEGER li, t_cnt;
-
- DBUG_ASSERT(sizeof(LARGE_INTEGER) == sizeof(query_performance_frequency));
-
- if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency) == 0)
- query_performance_frequency= 0;
- else
- {
- GetSystemTimeAsFileTime(&ft);
- li.LowPart= ft.dwLowDateTime;
- li.HighPart= ft.dwHighDateTime;
- query_performance_offset= li.QuadPart-OFFSET_TO_EPOC;
- QueryPerformanceCounter(&t_cnt);
- query_performance_offset-= (t_cnt.QuadPart /
- query_performance_frequency * MS +
- t_cnt.QuadPart %
- query_performance_frequency * MS /
- query_performance_frequency);
- }
-}
-
-
-/*
- Open HKEY_LOCAL_MACHINE\SOFTWARE\MySQL and set any strings found
- there as environment variables
-*/
-static void win_init_registry(void)
-{
- HKEY key_handle;
-
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)"SOFTWARE\\MySQL",
- 0, KEY_READ, &key_handle) == ERROR_SUCCESS)
- {
- LONG ret;
- DWORD index= 0;
- DWORD type;
- char key_name[256], key_data[1024];
- DWORD key_name_len= sizeof(key_name) - 1;
- DWORD key_data_len= sizeof(key_data) - 1;
-
- while ((ret= RegEnumValue(key_handle, index++,
- key_name, &key_name_len,
- NULL, &type, (LPBYTE)&key_data,
- &key_data_len)) != ERROR_NO_MORE_ITEMS)
- {
- char env_string[sizeof(key_name) + sizeof(key_data) + 2];
-
- if (ret == ERROR_MORE_DATA)
- {
- /* Registry value larger than 'key_data', skip it */
- DBUG_PRINT("error", ("Skipped registry value that was too large"));
- }
- else if (ret == ERROR_SUCCESS)
- {
- if (type == REG_SZ)
- {
- strxmov(env_string, key_name, "=", key_data, NullS);
-
- /* variable for putenv must be allocated ! */
- putenv(strdup(env_string)) ;
- }
- }
- else
- {
- /* Unhandled error, break out of loop */
- break;
- }
-
- key_name_len= sizeof(key_name) - 1;
- key_data_len= sizeof(key_data) - 1;
- }
-
- RegCloseKey(key_handle);
- }
-}
-
-
-static void my_win_init(void)
-{
- DBUG_ENTER("my_win_init");
-
-#if defined(_MSC_VER)
-#if _MSC_VER < 1300
- /*
- Clear the OS system variable TZ and avoid the 100% CPU usage
- Only for old versions of Visual C++
- */
- _putenv("TZ=");
-#endif
-#if _MSC_VER >= 1400
- /* this is required to make crt functions return -1 appropriately */
- _set_invalid_parameter_handler(my_parameter_handler);
-#endif
-#endif
-
-#ifdef __MSVC_RUNTIME_CHECKS
- /*
- Install handler to send RTC (Runtime Error Check) warnings
- to log file
- */
- _RTC_SetErrorFunc(handle_rtc_failure);
-#endif
-
- _tzset();
-
- win_init_time();
- win_init_registry();
-
- DBUG_VOID_RETURN;
-}
-
-
-/*------------------------------------------------------------------
- Name: CheckForTcpip| Desc: checks if tcpip has been installed on system
- According to Microsoft Developers documentation the first registry
- entry should be enough to check if TCP/IP is installed, but as expected
- this doesn't work on all Win32 machines :(
-------------------------------------------------------------------*/
-
-#define TCPIPKEY "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"
-#define WINSOCK2KEY "SYSTEM\\CurrentControlSet\\Services\\Winsock2\\Parameters"
-#define WINSOCKKEY "SYSTEM\\CurrentControlSet\\Services\\Winsock\\Parameters"
-
-static my_bool win32_have_tcpip(void)
-{
- HKEY hTcpipRegKey;
- if (RegOpenKeyEx ( HKEY_LOCAL_MACHINE, TCPIPKEY, 0, KEY_READ,
- &hTcpipRegKey) != ERROR_SUCCESS)
- {
- if (RegOpenKeyEx ( HKEY_LOCAL_MACHINE, WINSOCK2KEY, 0, KEY_READ,
- &hTcpipRegKey) != ERROR_SUCCESS)
- {
- if (RegOpenKeyEx ( HKEY_LOCAL_MACHINE, WINSOCKKEY, 0, KEY_READ,
- &hTcpipRegKey) != ERROR_SUCCESS)
- if (!getenv("HAVE_TCPIP") || have_tcpip) /* Provide a workaround */
- return (FALSE);
- }
- }
- RegCloseKey ( hTcpipRegKey);
- return (TRUE);
-}
-
-
-static my_bool win32_init_tcp_ip()
-{
- if (win32_have_tcpip())
- {
- WORD wVersionRequested = MAKEWORD( 2, 2 );
- WSADATA wsaData;
- /* Be a good citizen: maybe another lib has already initialised
- sockets, so dont clobber them unless necessary */
- if (WSAStartup( wVersionRequested, &wsaData ))
- {
- /* Load failed, maybe because of previously loaded
- incompatible version; try again */
- WSACleanup( );
- if (!WSAStartup( wVersionRequested, &wsaData ))
- have_tcpip=1;
- }
- else
- {
- if (wsaData.wVersion != wVersionRequested)
- {
- /* Version is no good, try again */
- WSACleanup( );
- if (!WSAStartup( wVersionRequested, &wsaData ))
- have_tcpip=1;
- }
- else
- have_tcpip=1;
- }
- }
- return(0);
-}
-#endif /* __WIN__ */
-
-#ifdef HAVE_PSI_INTERFACE
-
-#if !defined(HAVE_PREAD) && !defined(_WIN32)
-PSI_mutex_key key_my_file_info_mutex;
-#endif /* !defined(HAVE_PREAD) && !defined(_WIN32) */
-
-#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
-PSI_mutex_key key_LOCK_localtime_r;
-#endif /* !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) */
-
-#ifndef HAVE_GETHOSTBYNAME_R
-PSI_mutex_key key_LOCK_gethostbyname_r;
-#endif /* HAVE_GETHOSTBYNAME_R */
-
-PSI_mutex_key key_BITMAP_mutex, key_IO_CACHE_append_buffer_lock,
- key_IO_CACHE_SHARE_mutex, key_KEY_CACHE_cache_lock, key_LOCK_alarm,
- key_my_thread_var_mutex, key_THR_LOCK_charset, key_THR_LOCK_heap,
- key_THR_LOCK_isam, key_THR_LOCK_lock, key_THR_LOCK_malloc,
- key_THR_LOCK_mutex, key_THR_LOCK_myisam, key_THR_LOCK_net,
- key_THR_LOCK_open, key_THR_LOCK_threads, key_THR_LOCK_time,
- key_TMPDIR_mutex, key_THR_LOCK_myisam_mmap;
-
-static PSI_mutex_info all_mysys_mutexes[]=
-{
-#if !defined(HAVE_PREAD) && !defined(_WIN32)
- { &key_my_file_info_mutex, "st_my_file_info:mutex", 0},
-#endif /* !defined(HAVE_PREAD) && !defined(_WIN32) */
-#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
- { &key_LOCK_localtime_r, "LOCK_localtime_r", PSI_FLAG_GLOBAL},
-#endif /* !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) */
-#ifndef HAVE_GETHOSTBYNAME_R
- { &key_LOCK_gethostbyname_r, "LOCK_gethostbyname_r", PSI_FLAG_GLOBAL},
-#endif /* HAVE_GETHOSTBYNAME_R */
- { &key_BITMAP_mutex, "BITMAP::mutex", 0},
- { &key_IO_CACHE_append_buffer_lock, "IO_CACHE::append_buffer_lock", 0},
- { &key_IO_CACHE_SHARE_mutex, "IO_CACHE::SHARE_mutex", 0},
- { &key_KEY_CACHE_cache_lock, "KEY_CACHE::cache_lock", 0},
- { &key_LOCK_alarm, "LOCK_alarm", PSI_FLAG_GLOBAL},
- { &key_my_thread_var_mutex, "my_thread_var::mutex", 0},
- { &key_THR_LOCK_charset, "THR_LOCK_charset", PSI_FLAG_GLOBAL},
- { &key_THR_LOCK_heap, "THR_LOCK_heap", PSI_FLAG_GLOBAL},
- { &key_THR_LOCK_isam, "THR_LOCK_isam", PSI_FLAG_GLOBAL},
- { &key_THR_LOCK_lock, "THR_LOCK_lock", PSI_FLAG_GLOBAL},
- { &key_THR_LOCK_malloc, "THR_LOCK_malloc", PSI_FLAG_GLOBAL},
- { &key_THR_LOCK_mutex, "THR_LOCK::mutex", 0},
- { &key_THR_LOCK_myisam, "THR_LOCK_myisam", PSI_FLAG_GLOBAL},
- { &key_THR_LOCK_net, "THR_LOCK_net", PSI_FLAG_GLOBAL},
- { &key_THR_LOCK_open, "THR_LOCK_open", PSI_FLAG_GLOBAL},
- { &key_THR_LOCK_threads, "THR_LOCK_threads", PSI_FLAG_GLOBAL},
- { &key_THR_LOCK_time, "THR_LOCK_time", PSI_FLAG_GLOBAL},
- { &key_TMPDIR_mutex, "TMPDIR_mutex", PSI_FLAG_GLOBAL},
- { &key_THR_LOCK_myisam_mmap, "THR_LOCK_myisam_mmap", PSI_FLAG_GLOBAL}
-};
-
-PSI_cond_key key_COND_alarm, key_IO_CACHE_SHARE_cond,
- key_IO_CACHE_SHARE_cond_writer, key_my_thread_var_suspend,
- key_THR_COND_threads;
-
-static PSI_cond_info all_mysys_conds[]=
-{
- { &key_COND_alarm, "COND_alarm", PSI_FLAG_GLOBAL},
- { &key_IO_CACHE_SHARE_cond, "IO_CACHE_SHARE::cond", 0},
- { &key_IO_CACHE_SHARE_cond_writer, "IO_CACHE_SHARE::cond_writer", 0},
- { &key_my_thread_var_suspend, "my_thread_var::suspend", 0},
- { &key_THR_COND_threads, "THR_COND_threads", 0}
-};
-
-#ifdef USE_ALARM_THREAD
-PSI_thread_key key_thread_alarm;
-
-static PSI_thread_info all_mysys_threads[]=
-{
- { &key_thread_alarm, "alarm", PSI_FLAG_GLOBAL}
-};
-#endif /* USE_ALARM_THREAD */
-
-#ifdef HUGETLB_USE_PROC_MEMINFO
-PSI_file_key key_file_proc_meminfo;
-#endif /* HUGETLB_USE_PROC_MEMINFO */
-PSI_file_key key_file_charset, key_file_cnf;
-
-static PSI_file_info all_mysys_files[]=
-{
-#ifdef HUGETLB_USE_PROC_MEMINFO
- { &key_file_proc_meminfo, "proc_meminfo", 0},
-#endif /* HUGETLB_USE_PROC_MEMINFO */
- { &key_file_charset, "charset", 0},
- { &key_file_cnf, "cnf", 0}
-};
-
-void my_init_mysys_psi_keys()
-{
- const char* category= "mysys";
- int count;
-
- if (PSI_server == NULL)
- return;
-
- count= sizeof(all_mysys_mutexes)/sizeof(all_mysys_mutexes[0]);
- PSI_server->register_mutex(category, all_mysys_mutexes, count);
-
- count= sizeof(all_mysys_conds)/sizeof(all_mysys_conds[0]);
- PSI_server->register_cond(category, all_mysys_conds, count);
-
-#ifdef USE_ALARM_THREAD
- count= sizeof(all_mysys_threads)/sizeof(all_mysys_threads[0]);
- PSI_server->register_thread(category, all_mysys_threads, count);
-#endif /* USE_ALARM_THREAD */
-
- count= sizeof(all_mysys_files)/sizeof(all_mysys_files[0]);
- PSI_server->register_file(category, all_mysys_files, count);
-}
-#endif /* HAVE_PSI_INTERFACE */
-
diff --git a/dep/mysqllite/mysys/my_largepage.c b/dep/mysqllite/mysys/my_largepage.c
deleted file mode 100644
index 9f5ab01a2b7..00000000000
--- a/dep/mysqllite/mysys/my_largepage.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/* Copyright (C) 2004 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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"
-
-#ifdef HAVE_LARGE_PAGES
-
-#ifdef HAVE_SYS_IPC_H
-#include <sys/ipc.h>
-#endif
-
-#ifdef HAVE_SYS_SHM_H
-#include <sys/shm.h>
-#endif
-
-static uint my_get_large_page_size_int(void);
-static uchar* my_large_malloc_int(size_t size, myf my_flags);
-static my_bool my_large_free_int(uchar* ptr);
-
-/* Gets the size of large pages from the OS */
-
-uint my_get_large_page_size(void)
-{
- uint size;
- DBUG_ENTER("my_get_large_page_size");
-
- if (!(size = my_get_large_page_size_int()))
- fprintf(stderr, "Warning: Failed to determine large page size\n");
-
- DBUG_RETURN(size);
-}
-
-/*
- General large pages allocator.
- Tries to allocate memory from large pages pool and falls back to
- my_malloc_lock() in case of failure
-*/
-
-uchar* my_large_malloc(size_t size, myf my_flags)
-{
- uchar* ptr;
- DBUG_ENTER("my_large_malloc");
-
- if (my_use_large_pages && my_large_page_size)
- {
- if ((ptr = my_large_malloc_int(size, my_flags)) != NULL)
- DBUG_RETURN(ptr);
- if (my_flags & MY_WME)
- fprintf(stderr, "Warning: Using conventional memory pool\n");
- }
-
- DBUG_RETURN(my_malloc_lock(size, my_flags));
-}
-
-/*
- General large pages deallocator.
- Tries to deallocate memory as if it was from large pages pool and falls back
- to my_free_lock() in case of failure
- */
-
-void my_large_free(uchar* ptr)
-{
- DBUG_ENTER("my_large_free");
-
- /*
- my_large_free_int() can only fail if ptr was not allocated with
- my_large_malloc_int(), i.e. my_malloc_lock() was used so we should free it
- with my_free_lock()
- */
- if (!my_use_large_pages || !my_large_page_size || !my_large_free_int(ptr))
- my_free_lock(ptr);
-
- DBUG_VOID_RETURN;
-}
-
-#ifdef HUGETLB_USE_PROC_MEMINFO
-/* Linux-specific function to determine the size of large pages */
-
-uint my_get_large_page_size_int(void)
-{
- MYSQL_FILE *f;
- uint size = 0;
- char buf[256];
- DBUG_ENTER("my_get_large_page_size_int");
-
- if (!(f= mysql_file_fopen(key_file_proc_meminfo, "/proc/meminfo",
- O_RDONLY, MYF(MY_WME))))
- goto finish;
-
- while (mysql_file_fgets(buf, sizeof(buf), f))
- if (sscanf(buf, "Hugepagesize: %u kB", &size))
- break;
-
- mysql_file_fclose(f, MYF(MY_WME));
-
-finish:
- DBUG_RETURN(size * 1024);
-}
-#endif /* HUGETLB_USE_PROC_MEMINFO */
-
-#if HAVE_DECL_SHM_HUGETLB
-/* Linux-specific large pages allocator */
-
-uchar* my_large_malloc_int(size_t size, myf my_flags)
-{
- int shmid;
- uchar* ptr;
- struct shmid_ds buf;
- DBUG_ENTER("my_large_malloc_int");
-
- /* Align block size to my_large_page_size */
- size= MY_ALIGN(size, (size_t) my_large_page_size);
-
- shmid = shmget(IPC_PRIVATE, size, SHM_HUGETLB | SHM_R | SHM_W);
- if (shmid < 0)
- {
- if (my_flags & MY_WME)
- fprintf(stderr,
- "Warning: Failed to allocate %lu bytes from HugeTLB memory."
- " errno %d\n", (ulong) size, errno);
-
- DBUG_RETURN(NULL);
- }
-
- ptr = (uchar*) shmat(shmid, NULL, 0);
- if (ptr == (uchar *) -1)
- {
- if (my_flags& MY_WME)
- fprintf(stderr, "Warning: Failed to attach shared memory segment,"
- " errno %d\n", errno);
- shmctl(shmid, IPC_RMID, &buf);
-
- DBUG_RETURN(NULL);
- }
-
- /*
- Remove the shared memory segment so that it will be automatically freed
- after memory is detached or process exits
- */
- shmctl(shmid, IPC_RMID, &buf);
-
- DBUG_RETURN(ptr);
-}
-
-/* Linux-specific large pages deallocator */
-
-my_bool my_large_free_int(uchar *ptr)
-{
- DBUG_ENTER("my_large_free_int");
- DBUG_RETURN(shmdt(ptr) == 0);
-}
-#endif /* HAVE_DECL_SHM_HUGETLB */
-
-#endif /* HAVE_LARGE_PAGES */
diff --git a/dep/mysqllite/mysys/my_lib.c b/dep/mysqllite/mysys/my_lib.c
deleted file mode 100644
index 06f9521a664..00000000000
--- a/dep/mysqllite/mysys/my_lib.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 */
-
-/* TODO: check for overun of memory for names. */
-
-#include "mysys_priv.h"
-#include <m_string.h>
-#include <my_dir.h> /* Structs used by my_dir,includes sys/types */
-#include "mysys_err.h"
-#if defined(HAVE_DIRENT_H)
-# include <dirent.h>
-# define NAMLEN(dirent) strlen((dirent)->d_name)
-#else
-# define dirent direct
-# define NAMLEN(dirent) (dirent)->d_namlen
-# if defined(HAVE_SYS_NDIR_H)
-# include <sys/ndir.h>
-# endif
-# if defined(HAVE_SYS_DIR_H)
-# include <sys/dir.h>
-# endif
-# if defined(HAVE_NDIR_H)
-# include <ndir.h>
-# endif
-# if defined(_WIN32)
-# ifdef __BORLANDC__
-# include <dir.h>
-# endif
-# endif
-#endif
-
-#if defined(HAVE_READDIR_R)
-#define READDIR(A,B,C) ((errno=readdir_r(A,B,&C)) != 0 || !C)
-#else
-#define READDIR(A,B,C) (!(C=readdir(A)))
-#endif
-
-/*
- We are assuming that directory we are reading is either has less than
- 100 files and so can be read in one initial chunk or has more than 1000
- files and so big increment are suitable.
-*/
-#define ENTRIES_START_SIZE (8192/sizeof(FILEINFO))
-#define ENTRIES_INCREMENT (65536/sizeof(FILEINFO))
-#define NAMES_START_SIZE 32768
-
-
-static int comp_names(struct fileinfo *a,struct fileinfo *b);
-
-
- /* We need this because program don't know with malloc we used */
-
-void my_dirend(MY_DIR *buffer)
-{
- DBUG_ENTER("my_dirend");
- if (buffer)
- {
- delete_dynamic((DYNAMIC_ARRAY*)((char*)buffer +
- ALIGN_SIZE(sizeof(MY_DIR))));
- free_root((MEM_ROOT*)((char*)buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
- ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))), MYF(0));
- my_free(buffer);
- }
- DBUG_VOID_RETURN;
-} /* my_dirend */
-
-
- /* Compare in sort of filenames */
-
-static int comp_names(struct fileinfo *a, struct fileinfo *b)
-{
- return (strcmp(a->name,b->name));
-} /* comp_names */
-
-
-#if !defined(_WIN32)
-
-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;
- DIR *dirp;
- struct dirent *dp;
- char tmp_path[FN_REFLEN+1],*tmp_file;
- char dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1];
-
- DBUG_ENTER("my_dir");
- DBUG_PRINT("my",("path: '%s' MyFlags: %d",path,MyFlags));
-
-#if !defined(HAVE_READDIR_R)
- mysql_mutex_lock(&THR_LOCK_open);
-#endif
-
- dirp = opendir(directory_file_name(tmp_path,(char *) path));
-#if defined(__amiga__)
- if ((dirp->dd_fd) < 0) /* Directory doesn't exists */
- goto error;
-#endif
- if (dirp == NULL ||
- ! (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(buffer);
- 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;
-
- tmp_file=strend(tmp_path);
-
- dp= (struct dirent*) dirent_tmp;
-
- while (!(READDIR(dirp,(struct dirent*) dirent_tmp,dp)))
- {
- if (!(finfo.name= strdup_root(names_storage, dp->d_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));
- (void) strmov(tmp_file,dp->d_name);
- (void) my_stat(tmp_path, finfo.mystat, MyFlags);
- if (!(finfo.mystat->st_mode & MY_S_IREAD))
- continue;
- }
- else
- finfo.mystat= NULL;
-
- if (push_dynamic(dir_entries_storage, (uchar*)&finfo))
- goto error;
- }
-
- (void) closedir(dirp);
-#if !defined(HAVE_READDIR_R)
- mysql_mutex_unlock(&THR_LOCK_open);
-#endif
- result->dir_entry= (FILEINFO *)dir_entries_storage->buffer;
- result->number_off_files= dir_entries_storage->elements;
-
- if (!(MyFlags & MY_DONT_SORT))
- my_qsort((void *) result->dir_entry, result->number_off_files,
- sizeof(FILEINFO), (qsort_cmp) comp_names);
- DBUG_RETURN(result);
-
- error:
-#if !defined(HAVE_READDIR_R)
- mysql_mutex_unlock(&THR_LOCK_open);
-#endif
- my_errno=errno;
- if (dirp)
- (void) closedir(dirp);
- my_dirend(result);
- if (MyFlags & (MY_FAE | MY_WME))
- my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,my_errno);
- DBUG_RETURN((MY_DIR *) NULL);
-} /* my_dir */
-
-
-/*
- * Convert from directory name to filename.
- * On UNIX, it's simple: just make sure there is a terminating /
-
- * Returns pointer to dst;
- */
-
-char * directory_file_name (char * dst, const char *src)
-{
- /* Process as Unix format: just remove test the final slash. */
- char *end;
-
- if (src[0] == 0)
- src= (char*) "."; /* Use empty as current */
- end=strmov(dst, src);
- if (end[-1] != FN_LIBCHAR)
- {
- end[0]=FN_LIBCHAR; /* Add last '/' */
- end[1]='\0';
- }
- return dst;
-}
-
-#else
-
-/*
-*****************************************************************************
-** Read long filename using windows rutines
-*****************************************************************************
-*/
-
-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;
-#ifdef __BORLANDC__
- struct ffblk find;
-#else
- struct _finddata_t find;
-#endif
- ushort mode;
- char tmp_path[FN_REFLEN],*tmp_file,attrib;
-#ifdef _WIN64
- __int64 handle;
-#else
- long handle;
-#endif
- 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= strnmov(tmp_file, path, FN_REFLEN-5);
- 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]='*'; /* Windows needs this !??? */
- tmp_file[1]='.';
- tmp_file[2]='*';
- tmp_file[3]='\0';
-
- 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(buffer);
- 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;
-
-#ifdef __BORLANDC__
- if ((handle= findfirst(tmp_path,&find,0)) == -1L)
-#else
- if ((handle=_findfirst(tmp_path,&find)) == -1L)
-#endif
- {
- DBUG_PRINT("info", ("findfirst returned error, errno: %d", errno));
- if (errno != EINVAL)
- goto error;
- /*
- Could not read the directory, no read access.
- Probably because by "chmod -r".
- continue and return zero files in dir
- */
- }
- else
- {
-
- do
- {
-#ifdef __BORLANDC__
- attrib= find.ff_attrib;
-#else
- attrib= find.attrib;
- /*
- Do not show hidden and system files which Windows sometimes create.
- Note. Because Borland's findfirst() is called with the third
- argument = 0 hidden/system files are excluded from the search.
- */
- if (attrib & (_A_HIDDEN | _A_SYSTEM))
- continue;
-#endif
-#ifdef __BORLANDC__
- if (!(finfo.name= strdup_root(names_storage, find.ff_name)))
- goto error;
-#else
- if (!(finfo.name= strdup_root(names_storage, find.name)))
- goto error;
-#endif
- 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));
-#ifdef __BORLANDC__
- finfo.mystat->st_size=find.ff_fsize;
-#else
- finfo.mystat->st_size=find.size;
-#endif
- mode= MY_S_IREAD;
- if (!(attrib & _A_RDONLY))
- mode|= MY_S_IWRITE;
- if (attrib & _A_SUBDIR)
- mode|= MY_S_IFDIR;
- finfo.mystat->st_mode= mode;
-#ifdef __BORLANDC__
- finfo.mystat->st_mtime= ((uint32) find.ff_ftime);
-#else
- finfo.mystat->st_mtime= ((uint32) find.time_write);
-#endif
- }
- else
- finfo.mystat= NULL;
-
- if (push_dynamic(dir_entries_storage, (uchar*)&finfo))
- goto error;
- }
-#ifdef __BORLANDC__
- while (findnext(&find) == 0);
-#else
- while (_findnext(handle,&find) == 0);
-
- _findclose(handle);
-#endif
- }
-
- result->dir_entry= (FILEINFO *)dir_entries_storage->buffer;
- result->number_off_files= dir_entries_storage->elements;
-
- if (!(MyFlags & MY_DONT_SORT))
- my_qsort((void *) result->dir_entry, result->number_off_files,
- sizeof(FILEINFO), (qsort_cmp) comp_names);
- DBUG_PRINT("exit", ("found %d files", result->number_off_files));
- DBUG_RETURN(result);
-error:
- my_errno=errno;
-#ifndef __BORLANDC__
- if (handle != -1)
- _findclose(handle);
-#endif
- 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 */
-
-/****************************************************************************
-** File status
-** Note that MY_STAT is assumed to be same as struct stat
-****************************************************************************/
-
-
-int my_fstat(File Filedes, MY_STAT *stat_area,
- myf MyFlags __attribute__((unused)))
-{
- DBUG_ENTER("my_fstat");
- DBUG_PRINT("my",("fd: %d MyFlags: %d", Filedes, MyFlags));
-#ifdef _WIN32
- DBUG_RETURN(my_win_fstat(Filedes, stat_area));
-#else
- DBUG_RETURN(fstat(Filedes, (struct stat *) stat_area));
-#endif
-}
-
-
-MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags)
-{
- int m_used;
- DBUG_ENTER("my_stat");
- DBUG_PRINT("my", ("path: '%s' stat_area: 0x%lx MyFlags: %d", path,
- (long) stat_area, my_flags));
-
- if ((m_used= (stat_area == NULL)))
- if (!(stat_area= (MY_STAT *) my_malloc(sizeof(MY_STAT), my_flags)))
- goto error;
-#ifndef _WIN32
- if (! stat((char *) path, (struct stat *) stat_area) )
- DBUG_RETURN(stat_area);
-#else
- if (! my_win_stat(path, stat_area) )
- DBUG_RETURN(stat_area);
-#endif
- DBUG_PRINT("error",("Got errno: %d from stat", errno));
- my_errno= errno;
- if (m_used) /* Free if new area */
- my_free(stat_area);
-
-error:
- if (my_flags & (MY_FAE+MY_WME))
- {
- my_error(EE_STAT, MYF(ME_BELL+ME_WAITTANG),path,my_errno);
- DBUG_RETURN((MY_STAT *) NULL);
- }
- DBUG_RETURN((MY_STAT *) NULL);
-} /* my_stat */
diff --git a/dep/mysqllite/mysys/my_libwrap.c b/dep/mysqllite/mysys/my_libwrap.c
deleted file mode 100644
index e72334ba806..00000000000
--- a/dep/mysqllite/mysys/my_libwrap.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright (C) 2003 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 */
-
-/*
- This is needed to be able to compile with original libwrap header
- files that don't have the prototypes
-*/
-
-#include <my_global.h>
-#include <my_libwrap.h>
-
-#ifdef HAVE_LIBWRAP
-
-void my_fromhost(struct request_info *req)
-{
- fromhost(req);
-}
-
-int my_hosts_access(struct request_info *req)
-{
- return hosts_access(req);
-}
-
-char *my_eval_client(struct request_info *req)
-{
- return eval_client(req);
-}
-
-#endif /* HAVE_LIBWRAP */
diff --git a/dep/mysqllite/mysys/my_lock.c b/dep/mysqllite/mysys/my_lock.c
deleted file mode 100644
index 49c94ea838c..00000000000
--- a/dep/mysqllite/mysys/my_lock.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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"
-#include <errno.h>
-#undef MY_HOW_OFTEN_TO_ALARM
-#define MY_HOW_OFTEN_TO_ALARM ((int) my_time_to_wait_for_lock)
-#ifdef NO_ALARM_LOOP
-#undef NO_ALARM_LOOP
-#endif
-#include <my_alarm.h>
-
-#ifdef _WIN32
-#define WIN_LOCK_INFINITE -1
-#define WIN_LOCK_SLEEP_MILLIS 100
-
-static int win_lock(File fd, int locktype, my_off_t start, my_off_t length,
- int timeout_sec)
-{
- LARGE_INTEGER liOffset,liLength;
- DWORD dwFlags;
- OVERLAPPED ov= {0};
- HANDLE hFile= (HANDLE)my_get_osfhandle(fd);
- DWORD lastError= 0;
- int i;
- int timeout_millis= timeout_sec * 1000;
-
- DBUG_ENTER("win_lock");
-
- liOffset.QuadPart= start;
- liLength.QuadPart= length;
-
- ov.Offset= liOffset.LowPart;
- ov.OffsetHigh= liOffset.HighPart;
-
- if (locktype == F_UNLCK)
- {
- if (UnlockFileEx(hFile, 0, liLength.LowPart, liLength.HighPart, &ov))
- DBUG_RETURN(0);
- /*
- For compatibility with fcntl implementation, ignore error,
- if region was not locked
- */
- if (GetLastError() == ERROR_NOT_LOCKED)
- {
- SetLastError(0);
- DBUG_RETURN(0);
- }
- goto error;
- }
- else if (locktype == F_RDLCK)
- /* read lock is mapped to a shared lock. */
- dwFlags= 0;
- else
- /* write lock is mapped to an exclusive lock. */
- dwFlags= LOCKFILE_EXCLUSIVE_LOCK;
-
- /*
- Drop old lock first to avoid double locking.
- During analyze of Bug#38133 (Myisamlog test fails on Windows)
- I met the situation that the program myisamlog locked the file
- exclusively, then additionally shared, then did one unlock, and
- then blocked on an attempt to lock it exclusively again.
- Unlocking before every lock fixed the problem.
- Note that this introduces a race condition. When the application
- wants to convert an exclusive lock into a shared one, it will now
- first unlock the file and then lock it shared. A waiting exclusive
- lock could step in here. For reasons described in Bug#38133 and
- Bug#41124 (Server hangs on Windows with --external-locking after
- INSERT...SELECT) and in the review thread at
- http://lists.mysql.com/commits/60721 it seems to be the better
- option than not to unlock here.
- If one day someone notices a way how to do file lock type changes
- on Windows without unlocking before taking the new lock, please
- change this code accordingly to fix the race condition.
- */
- if (!UnlockFileEx(hFile, 0, liLength.LowPart, liLength.HighPart, &ov) &&
- (GetLastError() != ERROR_NOT_LOCKED))
- goto error;
-
- if (timeout_sec == WIN_LOCK_INFINITE)
- {
- if (LockFileEx(hFile, dwFlags, 0, liLength.LowPart, liLength.HighPart, &ov))
- DBUG_RETURN(0);
- goto error;
- }
-
- dwFlags|= LOCKFILE_FAIL_IMMEDIATELY;
- timeout_millis= timeout_sec * 1000;
- /* Try lock in a loop, until the lock is acquired or timeout happens */
- for(i= 0; ;i+= WIN_LOCK_SLEEP_MILLIS)
- {
- if (LockFileEx(hFile, dwFlags, 0, liLength.LowPart, liLength.HighPart, &ov))
- DBUG_RETURN(0);
-
- if (GetLastError() != ERROR_LOCK_VIOLATION)
- goto error;
-
- if (i >= timeout_millis)
- break;
- Sleep(WIN_LOCK_SLEEP_MILLIS);
- }
-
- /* timeout */
- errno= EAGAIN;
- DBUG_RETURN(-1);
-
-error:
- my_osmaperr(GetLastError());
- DBUG_RETURN(-1);
-}
-#endif
-
-
-
-/*
- Lock a part of a file
-
- RETURN VALUE
- 0 Success
- -1 An error has occured and 'my_errno' is set
- to indicate the actual error code.
-*/
-
-int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
- myf MyFlags)
-{
-#ifdef HAVE_FCNTL
- int value;
- ALARM_VARIABLES;
-#endif
-
- DBUG_ENTER("my_lock");
- DBUG_PRINT("my",("fd: %d Op: %d start: %ld Length: %ld MyFlags: %d",
- fd,locktype,(long) start,(long) length,MyFlags));
- if (my_disable_locking)
- DBUG_RETURN(0);
-
-#if defined(_WIN32)
- {
- int timeout_sec;
- if (MyFlags & MY_DONT_WAIT)
- timeout_sec= 0;
- else
- timeout_sec= WIN_LOCK_INFINITE;
-
- if (win_lock(fd, locktype, start, length, timeout_sec) == 0)
- DBUG_RETURN(0);
- }
-#else
-#if defined(HAVE_FCNTL)
- {
- struct flock lock;
-
- lock.l_type= (short) locktype;
- lock.l_whence= SEEK_SET;
- lock.l_start= (off_t) start;
- lock.l_len= (off_t) length;
-
- if (MyFlags & MY_DONT_WAIT)
- {
- if (fcntl(fd,F_SETLK,&lock) != -1) /* Check if we can lock */
- DBUG_RETURN(0); /* Ok, file locked */
- DBUG_PRINT("info",("Was locked, trying with alarm"));
- ALARM_INIT;
- while ((value=fcntl(fd,F_SETLKW,&lock)) && ! ALARM_TEST &&
- errno == EINTR)
- { /* Setup again so we don`t miss it */
- ALARM_REINIT;
- }
- ALARM_END;
- if (value != -1)
- DBUG_RETURN(0);
- if (errno == EINTR)
- errno=EAGAIN;
- }
- else if (fcntl(fd,F_SETLKW,&lock) != -1) /* Wait until a lock */
- DBUG_RETURN(0);
- }
-#else
- if (MyFlags & MY_SEEK_NOT_DONE)
- {
- if (my_seek(fd,start,MY_SEEK_SET,MYF(MyFlags & ~MY_SEEK_NOT_DONE))
- == MY_FILEPOS_ERROR)
- {
- /*
- If an error has occured in my_seek then we will already
- have an error code in my_errno; Just return error code.
- */
- DBUG_RETURN(-1);
- }
- }
- if (lockf(fd,locktype,length) != -1)
- DBUG_RETURN(0);
-#endif /* HAVE_FCNTL */
-#endif /* HAVE_LOCKING */
-
- /* We got an error. We don't want EACCES errors */
- my_errno=(errno == EACCES) ? EAGAIN : errno ? errno : -1;
-
- if (MyFlags & MY_WME)
- {
- if (locktype == F_UNLCK)
- my_error(EE_CANTUNLOCK,MYF(ME_BELL+ME_WAITTANG),my_errno);
- else
- my_error(EE_CANTLOCK,MYF(ME_BELL+ME_WAITTANG),my_errno);
- }
- DBUG_PRINT("error",("my_errno: %d (%d)",my_errno,errno));
- DBUG_RETURN(-1);
-} /* my_lock */
diff --git a/dep/mysqllite/mysys/my_lockmem.c b/dep/mysqllite/mysys/my_lockmem.c
deleted file mode 100644
index a37db6b2089..00000000000
--- a/dep/mysqllite/mysys/my_lockmem.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 */
-
-/* Alloc a block of locked memory */
-
-#include "mysys_priv.h"
-#include "mysys_err.h"
-#include <my_list.h>
-
-#ifdef HAVE_MLOCK
-#include <sys/mman.h>
-
-struct st_mem_list
-{
- LIST list;
- uchar *page;
- uint size;
-};
-
-LIST *mem_list;
-
-uchar *my_malloc_lock(uint size,myf MyFlags)
-{
- int success;
- uint pagesize=sysconf(_SC_PAGESIZE);
- uchar *ptr;
- struct st_mem_list *element;
- DBUG_ENTER("my_malloc_lock");
-
- size=((size-1) & ~(pagesize-1))+pagesize;
- if (!(ptr=memalign(pagesize,size)))
- {
- if (MyFlags & (MY_FAE+MY_WME))
- my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG),size);
- DBUG_RETURN(0);
- }
- success = mlock((uchar*) ptr,size);
- if (success != 0 && geteuid() == 0)
- {
- DBUG_PRINT("warning",("Failed to lock memory. errno %d\n",
- errno));
- fprintf(stderr, "Warning: Failed to lock memory. errno %d\n",
- errno);
- }
- else
- {
- /* Add block in a list for munlock */
- if (!(element=(struct st_mem_list*) my_malloc(sizeof(*element),MyFlags)))
- {
- (void) munlock((uchar*) ptr,size);
- free(ptr);
- DBUG_RETURN(0);
- }
- element->list.data=(uchar*) element;
- element->page=ptr;
- element->size=size;
- mysql_mutex_lock(&THR_LOCK_malloc);
- mem_list=list_add(mem_list,&element->list);
- mysql_mutex_unlock(&THR_LOCK_malloc);
- }
- DBUG_RETURN(ptr);
-}
-
-
-void my_free_lock(uchar *ptr)
-{
- LIST *list;
- struct st_mem_list *element=0;
-
- mysql_mutex_lock(&THR_LOCK_malloc);
- for (list=mem_list ; list ; list=list->next)
- {
- element=(struct st_mem_list*) list->data;
- if (ptr == element->page)
- { /* Found locked mem */
- (void) munlock((uchar*) ptr,element->size);
- mem_list=list_delete(mem_list,list);
- break;
- }
- }
- mysql_mutex_unlock(&THR_LOCK_malloc);
- my_free(element);
- free(ptr); /* Free even if not locked */
-}
-
-#endif /* HAVE_MLOCK */
diff --git a/dep/mysqllite/mysys/my_malloc.c b/dep/mysqllite/mysys/my_malloc.c
deleted file mode 100644
index fc2dc98c3c5..00000000000
--- a/dep/mysqllite/mysys/my_malloc.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
-
- 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 */
-
-#include "mysys_priv.h"
-#include "mysys_err.h"
-#include <m_string.h>
-
-/**
- Allocate a sized block of memory.
-
- @param size The size of the memory block in bytes.
- @param flags Failure action modifiers (bitmasks).
-
- @return A pointer to the allocated memory block, or NULL on failure.
-*/
-void *my_malloc(size_t size, myf my_flags)
-{
- void* point;
- DBUG_ENTER("my_malloc");
- DBUG_PRINT("my",("size: %lu my_flags: %d", (ulong) size, my_flags));
-
- /* Safety */
- if (!size)
- size=1;
-
- point= malloc(size);
- DBUG_EXECUTE_IF("simulate_out_of_memory",
- {
- free(point);
- point= NULL;
- });
-
- if (point == NULL)
- {
- my_errno=errno;
- if (my_flags & MY_FAE)
- error_handler_hook=fatal_error_handler_hook;
- if (my_flags & (MY_FAE+MY_WME))
- my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG+ME_NOREFRESH),size);
- DBUG_EXECUTE_IF("simulate_out_of_memory",
- DBUG_SET("-d,simulate_out_of_memory"););
- if (my_flags & MY_FAE)
- exit(1);
- }
- else if (my_flags & MY_ZEROFILL)
- bzero(point, size);
- DBUG_PRINT("exit",("ptr: %p", point));
- DBUG_RETURN(point);
-}
-
-
-/**
- @brief wrapper around realloc()
-
- @param oldpoint pointer to currently allocated area
- @param size new size requested, must be >0
- @param my_flags flags
-
- @note if size==0 realloc() may return NULL; my_realloc() treats this as an
- error which is not the intention of realloc()
-*/
-void *my_realloc(void *oldpoint, size_t size, myf my_flags)
-{
- void *point;
- DBUG_ENTER("my_realloc");
- DBUG_PRINT("my",("ptr: %p size: %lu my_flags: %d", oldpoint,
- (ulong) size, my_flags));
-
- DBUG_ASSERT(size > 0);
- if (!oldpoint && (my_flags & MY_ALLOW_ZERO_PTR))
- DBUG_RETURN(my_malloc(size, my_flags));
-#ifdef USE_HALLOC
- if (!(point = malloc(size)))
- {
- if (my_flags & MY_FREE_ON_ERROR)
- my_free(oldpoint);
- if (my_flags & MY_HOLD_ON_ERROR)
- DBUG_RETURN(oldpoint);
- my_errno=errno;
- if (my_flags & MY_FAE+MY_WME)
- my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG),size);
- }
- else
- {
- memcpy(point,oldpoint,size);
- free(oldpoint);
- }
-#else
- if ((point= realloc(oldpoint, size)) == NULL)
- {
- if (my_flags & MY_FREE_ON_ERROR)
- my_free(oldpoint);
- if (my_flags & MY_HOLD_ON_ERROR)
- DBUG_RETURN(oldpoint);
- my_errno=errno;
- if (my_flags & (MY_FAE+MY_WME))
- my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG), size);
- }
-#endif
- DBUG_PRINT("exit",("ptr: %p", point));
- DBUG_RETURN(point);
-}
-
-
-/**
- Free memory allocated with my_malloc.
-
- @remark Relies on free being able to handle a NULL argument.
-
- @param ptr Pointer to the memory allocated by my_malloc.
-*/
-void my_free(void *ptr)
-{
- DBUG_ENTER("my_free");
- DBUG_PRINT("my",("ptr: %p", ptr));
- free(ptr);
- DBUG_VOID_RETURN;
-}
-
-
-void *my_memdup(const void *from, size_t length, myf my_flags)
-{
- void *ptr;
- if ((ptr= my_malloc(length,my_flags)) != 0)
- memcpy(ptr, from, length);
- return ptr;
-}
-
-
-char *my_strdup(const char *from, myf my_flags)
-{
- char *ptr;
- size_t length= strlen(from)+1;
- if ((ptr= (char*) my_malloc(length, my_flags)))
- memcpy(ptr, from, length);
- return ptr;
-}
-
-
-char *my_strndup(const char *from, size_t length, myf my_flags)
-{
- char *ptr;
- if ((ptr= (char*) my_malloc(length+1, my_flags)))
- {
- memcpy(ptr, from, length);
- ptr[length]= 0;
- }
- return ptr;
-}
-
diff --git a/dep/mysqllite/mysys/my_memmem.c b/dep/mysqllite/mysys/my_memmem.c
deleted file mode 100644
index c000f14bc66..00000000000
--- a/dep/mysqllite/mysys/my_memmem.c
+++ /dev/null
@@ -1,83 +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 <my_global.h>
-#include <m_string.h>
-
-/*
- my_memmem, port of a GNU extension.
-
- Returns a pointer to the beginning of the substring, needle, or NULL if the
- substring is not found in haystack.
-*/
-
-void *my_memmem(const void *haystack, size_t haystacklen,
- const void *needle, size_t needlelen)
-{
- const unsigned char *cursor;
- const unsigned char *last_possible_needle_location =
- (unsigned char *)haystack + haystacklen - needlelen;
-
- /* Easy answers */
- if (needlelen > haystacklen) return(NULL);
- if (needle == NULL) return(NULL);
- if (haystack == NULL) return(NULL);
- if (needlelen == 0) return(NULL);
- if (haystacklen == 0) return(NULL);
-
- for (cursor = haystack; cursor <= last_possible_needle_location; cursor++) {
- if (memcmp(needle, cursor, needlelen) == 0) {
- return((void *) cursor);
- }
- }
- return(NULL);
-}
-
-
-
-#ifdef MAIN
-#include <assert.h>
-
-int main(int argc, char *argv[]) {
- char haystack[10], needle[3];
-
- memmove(haystack, "0123456789", 10);
-
- memmove(needle, "no", 2);
- assert(my_memmem(haystack, 10, needle, 2) == NULL);
-
- memmove(needle, "345", 3);
- assert(my_memmem(haystack, 10, needle, 3) != NULL);
-
- memmove(needle, "789", 3);
- assert(my_memmem(haystack, 10, needle, 3) != NULL);
- assert(my_memmem(haystack, 9, needle, 3) == NULL);
-
- memmove(needle, "012", 3);
- assert(my_memmem(haystack, 10, needle, 3) != NULL);
- assert(my_memmem(NULL, 10, needle, 3) == NULL);
-
- assert(my_memmem(NULL, 10, needle, 3) == NULL);
- assert(my_memmem(haystack, 0, needle, 3) == NULL);
- assert(my_memmem(haystack, 10, NULL, 3) == NULL);
- assert(my_memmem(haystack, 10, needle, 0) == NULL);
-
- assert(my_memmem(haystack, 1, needle, 3) == NULL);
-
- printf("success\n");
- return(0);
-}
-
-#endif
diff --git a/dep/mysqllite/mysys/my_mess.c b/dep/mysqllite/mysys/my_mess.c
deleted file mode 100644
index 513afe39054..00000000000
--- a/dep/mysqllite/mysys/my_mess.c
+++ /dev/null
@@ -1,34 +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"
-
-void my_message_stderr(uint error __attribute__((unused)),
- const char *str, myf MyFlags)
-{
- DBUG_ENTER("my_message_stderr");
- DBUG_PRINT("enter",("message: %s",str));
- (void) fflush(stdout);
- if (MyFlags & ME_BELL)
- (void) fputc('\007', stderr);
- if (my_progname)
- {
- (void)fputs(my_progname,stderr); (void)fputs(": ",stderr);
- }
- (void)fputs(str,stderr);
- (void)fputc('\n',stderr);
- (void)fflush(stderr);
- DBUG_VOID_RETURN;
-}
diff --git a/dep/mysqllite/mysys/my_mkdir.c b/dep/mysqllite/mysys/my_mkdir.c
deleted file mode 100644
index 676c6c1cd51..00000000000
--- a/dep/mysqllite/mysys/my_mkdir.c
+++ /dev/null
@@ -1,42 +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"
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifdef __WIN__
-#include <direct.h>
-#endif
-
-int my_mkdir(const char *dir, int Flags, myf MyFlags)
-{
- DBUG_ENTER("my_dir");
- DBUG_PRINT("enter",("dir: %s",dir));
-
-#if defined(__WIN__)
- if (mkdir((char*) dir))
-#else
- if (mkdir((char*) dir, Flags & my_umask_dir))
-#endif
- {
- my_errno=errno;
- DBUG_PRINT("error",("error %d when creating direcory %s",my_errno,dir));
- if (MyFlags & (MY_FFNF | MY_FAE | MY_WME))
- my_error(EE_CANT_MKDIR, MYF(ME_BELL+ME_WAITTANG), dir, my_errno);
- DBUG_RETURN(-1);
- }
- DBUG_RETURN(0);
-}
diff --git a/dep/mysqllite/mysys/my_mmap.c b/dep/mysqllite/mysys/my_mmap.c
deleted file mode 100644
index 82ee1562bc2..00000000000
--- a/dep/mysqllite/mysys/my_mmap.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/* Copyright (C) 2000-2003 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"
-
-#ifdef HAVE_SYS_MMAN_H
-
-/*
- system msync() only syncs mmap'ed area to fs cache.
- fsync() is required to really sync to disc
-*/
-int my_msync(int fd, void *addr, size_t len, int flags)
-{
- msync(addr, len, flags);
- return my_sync(fd, MYF(0));
-}
-
-#elif defined(_WIN32)
-
-static SECURITY_ATTRIBUTES mmap_security_attributes=
- {sizeof(SECURITY_ATTRIBUTES), 0, TRUE};
-
-void *my_mmap(void *addr, size_t len, int prot,
- int flags, File fd, my_off_t offset)
-{
- HANDLE hFileMap;
- LPVOID ptr;
- HANDLE hFile= (HANDLE)my_get_osfhandle(fd);
- DBUG_ENTER("my_mmap");
- DBUG_PRINT("mysys", ("map fd: %d", fd));
-
- if (hFile == INVALID_HANDLE_VALUE)
- DBUG_RETURN(MAP_FAILED);
-
- hFileMap=CreateFileMapping(hFile, &mmap_security_attributes,
- PAGE_READWRITE, 0, (DWORD) len, NULL);
- if (hFileMap == 0)
- DBUG_RETURN(MAP_FAILED);
-
- ptr=MapViewOfFile(hFileMap,
- prot & PROT_WRITE ? FILE_MAP_WRITE : FILE_MAP_READ,
- (DWORD)(offset >> 32), (DWORD)offset, len);
-
- /*
- MSDN explicitly states that it's possible to close File Mapping Object
- even when a view is not unmapped - then the object will be held open
- implicitly until unmap, as every view stores internally a handler of
- a corresponding File Mapping Object
- */
- CloseHandle(hFileMap);
-
- if (ptr)
- {
- DBUG_PRINT("mysys", ("mapped addr: %p", ptr));
- DBUG_RETURN(ptr);
- }
-
- DBUG_RETURN(MAP_FAILED);
-}
-
-int my_munmap(void *addr, size_t len)
-{
- DBUG_ENTER("my_munmap");
- DBUG_PRINT("mysys", ("unmap addr: %p", addr));
- DBUG_RETURN(UnmapViewOfFile(addr) ? 0 : -1);
-}
-
-int my_msync(int fd, void *addr, size_t len, int flags)
-{
- return FlushViewOfFile(addr, len) ? 0 : -1;
-}
-
-#else
-#warning "no mmap!"
-#endif
-
diff --git a/dep/mysqllite/mysys/my_new.cc b/dep/mysqllite/mysys/my_new.cc
deleted file mode 100644
index 7da54ffac87..00000000000
--- a/dep/mysqllite/mysys/my_new.cc
+++ /dev/null
@@ -1,58 +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 */
-
-/*
- This is a replacement of new/delete operators to be used when compiling
- with gcc 3.0.x to avoid including libstdc++
-*/
-
-#include "mysys_priv.h"
-
-#ifdef USE_MYSYS_NEW
-
-void *operator new (size_t sz)
-{
- return (void *) malloc (sz ? sz : 1);
-}
-
-void *operator new[] (size_t sz)
-{
- return (void *) malloc (sz ? sz : 1);
-}
-
-void operator delete (void *ptr)
-{
- if (ptr)
- free(ptr);
-}
-
-void operator delete[] (void *ptr) throw ()
-{
- if (ptr)
- free(ptr);
-}
-
-C_MODE_START
-
-int __cxa_pure_virtual()
-{
- assert(! "Aborted: pure virtual method called.");
- return 0;
-}
-
-C_MODE_END
-
-#endif /* USE_MYSYS_NEW */
-
diff --git a/dep/mysqllite/mysys/my_once.c b/dep/mysqllite/mysys/my_once.c
deleted file mode 100644
index 32d07802028..00000000000
--- a/dep/mysqllite/mysys/my_once.c
+++ /dev/null
@@ -1,119 +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 */
-
-/* Not MT-SAFE */
-
-#include "mysys_priv.h"
-#include "my_static.h"
-#include "mysys_err.h"
-#include <m_string.h>
-
-/*
- Alloc for things we don't nend to free run-time (that only
- should be free'd on exit)
-
- SYNOPSIS
- my_once_alloc()
- Size
- MyFlags
-
- NOTES
- No DBUG_ENTER... here to get smaller dbug-startup
-*/
-
-void* my_once_alloc(size_t Size, myf MyFlags)
-{
- size_t get_size, max_left;
- uchar* point;
- reg1 USED_MEM *next;
- reg2 USED_MEM **prev;
-
- Size= ALIGN_SIZE(Size);
- prev= &my_once_root_block;
- max_left=0;
- for (next=my_once_root_block ; next && next->left < Size ; next= next->next)
- {
- if (next->left > max_left)
- max_left=next->left;
- prev= &next->next;
- }
- if (! next)
- { /* Time to alloc new block */
- get_size= Size+ALIGN_SIZE(sizeof(USED_MEM));
- if (max_left*4 < my_once_extra && get_size < my_once_extra)
- get_size=my_once_extra; /* Normal alloc */
-
- if ((next = (USED_MEM*) malloc(get_size)) == 0)
- {
- my_errno=errno;
- if (MyFlags & (MY_FAE+MY_WME))
- my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG),get_size);
- return((uchar*) 0);
- }
- DBUG_PRINT("test",("my_once_malloc %lu byte malloced", (ulong) get_size));
- next->next= 0;
- next->size= get_size;
- next->left= get_size-ALIGN_SIZE(sizeof(USED_MEM));
- *prev=next;
- }
- point= (uchar*) ((char*) next+ (next->size-next->left));
- next->left-= Size;
-
- if (MyFlags & MY_ZEROFILL)
- bzero(point, Size);
- return((void*) point);
-} /* my_once_alloc */
-
-
-char *my_once_strdup(const char *src,myf myflags)
-{
- size_t len= strlen(src)+1;
- uchar *dst= my_once_alloc(len, myflags);
- if (dst)
- memcpy(dst, src, len);
- return (char*) dst;
-}
-
-
-void *my_once_memdup(const void *src, size_t len, myf myflags)
-{
- uchar *dst= my_once_alloc(len, myflags);
- if (dst)
- memcpy(dst, src, len);
- return dst;
-}
-
-
-/*
- Deallocate everything that was allocated with my_once_alloc
-
- SYNOPSIS
- my_once_free()
-*/
-
-void my_once_free(void)
-{
- reg1 USED_MEM *next,*old;
- DBUG_ENTER("my_once_free");
-
- for (next=my_once_root_block ; next ; )
- {
- old=next; next= next->next ;
- free((uchar*) old);
- }
- my_once_root_block=0;
-
- DBUG_VOID_RETURN;
-} /* my_once_free */
diff --git a/dep/mysqllite/mysys/my_open.c b/dep/mysqllite/mysys/my_open.c
deleted file mode 100644
index 2aef97b3e34..00000000000
--- a/dep/mysqllite/mysys/my_open.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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"
-#include <my_dir.h>
-#include <errno.h>
-
-
-/*
- Open a file
-
- SYNOPSIS
- my_open()
- FileName Fully qualified file name
- Flags Read | write
- MyFlags Special flags
-
- RETURN VALUE
- File descriptor
-*/
-
-File my_open(const char *FileName, int Flags, myf MyFlags)
- /* Path-name of file */
- /* Read | write .. */
- /* Special flags */
-{
- File fd;
- DBUG_ENTER("my_open");
- DBUG_PRINT("my",("Name: '%s' Flags: %d MyFlags: %d",
- FileName, Flags, MyFlags));
-#if defined(_WIN32)
- fd= my_win_open(FileName, Flags);
-#elif !defined(NO_OPEN_3)
- fd = open(FileName, Flags, my_umask); /* Normal unix */
-#else
- fd = open((char *) FileName, Flags);
-#endif
-
- DBUG_RETURN(my_register_filename(fd, FileName, FILE_BY_OPEN,
- EE_FILENOTFOUND, MyFlags));
-} /* my_open */
-
-
-/*
- Close a file
-
- SYNOPSIS
- my_close()
- fd File sescriptor
- myf Special Flags
-
-*/
-
-int my_close(File fd, myf MyFlags)
-{
- int err;
- DBUG_ENTER("my_close");
- DBUG_PRINT("my",("fd: %d MyFlags: %d",fd, MyFlags));
-
- mysql_mutex_lock(&THR_LOCK_open);
-#ifndef _WIN32
- do
- {
- err= close(fd);
- } while (err == -1 && errno == EINTR);
-#else
- err= my_win_close(fd);
-#endif
- if (err)
- {
- DBUG_PRINT("error",("Got error %d on close",err));
- my_errno=errno;
- if (MyFlags & (MY_FAE | MY_WME))
- my_error(EE_BADCLOSE, MYF(ME_BELL+ME_WAITTANG),my_filename(fd),errno);
- }
- if ((uint) fd < my_file_limit && my_file_info[fd].type != UNOPEN)
- {
- my_free(my_file_info[fd].name);
-#if !defined(HAVE_PREAD) && !defined(_WIN32)
- mysql_mutex_destroy(&my_file_info[fd].mutex);
-#endif
- my_file_info[fd].type = UNOPEN;
- }
- my_file_opened--;
- mysql_mutex_unlock(&THR_LOCK_open);
- DBUG_RETURN(err);
-} /* my_close */
-
-
-/*
- Register file in my_file_info[]
-
- SYNOPSIS
- my_register_filename()
- fd File number opened, -1 if error on open
- FileName File name
- type_file_type How file was created
- error_message_number Error message number if caller got error (fd == -1)
- MyFlags Flags for my_close()
-
- RETURN
- -1 error
- # Filenumber
-
-*/
-
-File my_register_filename(File fd, const char *FileName, enum file_type
- type_of_file, uint error_message_number, myf MyFlags)
-{
- DBUG_ENTER("my_register_filename");
- if ((int) fd >= MY_FILE_MIN)
- {
- if ((uint) fd >= my_file_limit)
- {
-#if !defined(HAVE_PREAD)
- my_errno= EMFILE;
-#else
- thread_safe_increment(my_file_opened,&THR_LOCK_open);
- DBUG_RETURN(fd); /* safeguard */
-#endif
- }
- else
- {
- mysql_mutex_lock(&THR_LOCK_open);
- if ((my_file_info[fd].name = (char*) my_strdup(FileName,MyFlags)))
- {
- my_file_opened++;
- my_file_total_opened++;
- my_file_info[fd].type = type_of_file;
-#if !defined(HAVE_PREAD) && !defined(_WIN32)
- mysql_mutex_init(key_my_file_info_mutex, &my_file_info[fd].mutex,
- MY_MUTEX_INIT_FAST);
-#endif
- mysql_mutex_unlock(&THR_LOCK_open);
- DBUG_PRINT("exit",("fd: %d",fd));
- DBUG_RETURN(fd);
- }
- mysql_mutex_unlock(&THR_LOCK_open);
- my_errno= ENOMEM;
- }
- (void) my_close(fd, MyFlags);
- }
- else
- my_errno= errno;
-
- DBUG_PRINT("error",("Got error %d on open", my_errno));
- if (MyFlags & (MY_FFNF | MY_FAE | MY_WME))
- {
- if (my_errno == EMFILE)
- error_message_number= EE_OUT_OF_FILERESOURCES;
- DBUG_PRINT("error",("print err: %d",error_message_number));
- my_error(error_message_number, MYF(ME_BELL+ME_WAITTANG),
- FileName, my_errno);
- }
- DBUG_RETURN(-1);
-}
-
-
-
-
-#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/dep/mysqllite/mysys/my_port.c b/dep/mysqllite/mysys/my_port.c
deleted file mode 100644
index 9ad333421ca..00000000000
--- a/dep/mysqllite/mysys/my_port.c
+++ /dev/null
@@ -1,40 +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 */
-
-/*
- Small functions to make code portable
-*/
-
-#include "mysys_priv.h"
-
-#ifdef _AIX
-
-/*
- On AIX, at least with gcc 3.1, the expression
- '(double) (ulonglong) var' doesn't always work for big unsigned
- integers like '18446744073709551615'. The end result is that the
- high bit is simply dropped. (probably bug in gcc optimizations)
- Handling the conversion in a sub function seems to work.
-*/
-
-
-
-double my_ulonglong2double(unsigned long long nr)
-{
- return (double) nr;
-}
-#endif /* _AIX */
diff --git a/dep/mysqllite/mysys/my_pread.c b/dep/mysqllite/mysys/my_pread.c
deleted file mode 100644
index e006360c11b..00000000000
--- a/dep/mysqllite/mysys/my_pread.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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"
-#include "my_base.h"
-#include <m_string.h>
-#include <errno.h>
-#if defined (HAVE_PREAD) && !defined(_WIN32)
-#include <unistd.h>
-#endif
-
-
-
-/*
- Read a chunk of bytes from a file from a given position
-
- SYNOPSIOS
- my_pread()
- Filedes File decsriptor
- Buffer Buffer to read data into
- Count Number of bytes to read
- offset Position to read from
- MyFlags Flags
-
- NOTES
- This differs from the normal pread() call in that we don't care
- to set the position in the file back to the original position
- if the system doesn't support pread().
-
- RETURN
- (size_t) -1 Error
- # Number of bytes read
-*/
-
-size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
- myf MyFlags)
-{
- size_t readbytes;
- int error= 0;
-#if !defined (HAVE_PREAD) && !defined (_WIN32)
- int save_errno;
-#endif
- DBUG_ENTER("my_pread");
- DBUG_PRINT("my",("fd: %d Seek: %llu Buffer: %p Count: %lu MyFlags: %d",
- Filedes, (ulonglong)offset, Buffer, (ulong)Count, MyFlags));
- for (;;)
- {
- errno= 0; /* Linux, Windows don't reset this on EOF/success */
-#if !defined (HAVE_PREAD) && !defined (_WIN32)
- mysql_mutex_lock(&my_file_info[Filedes].mutex);
- readbytes= (uint) -1;
- error= (lseek(Filedes, offset, MY_SEEK_SET) == (my_off_t) -1 ||
- (readbytes= read(Filedes, Buffer, Count)) != Count);
- save_errno= errno;
- mysql_mutex_unlock(&my_file_info[Filedes].mutex);
- if (error)
- errno= save_errno;
-#else
-#if defined(_WIN32)
- readbytes= my_win_pread(Filedes, Buffer, Count, offset);
-#else
- readbytes= pread(Filedes, Buffer, Count, offset);
-#endif
- error= (readbytes != Count);
-#endif
- if(error)
- {
- my_errno= errno ? errno : -1;
- if (errno == 0 || (readbytes != (size_t) -1 &&
- (MyFlags & (MY_NABP | MY_FNABP))))
- my_errno= HA_ERR_FILE_TOO_SHORT;
-
- DBUG_PRINT("warning",("Read only %d bytes off %u from %d, errno: %d",
- (int) readbytes, (uint) Count,Filedes,my_errno));
-
- if ((readbytes == 0 || readbytes == (size_t) -1) && errno == EINTR)
- {
- DBUG_PRINT("debug", ("my_pread() was interrupted and returned %d",
- (int) readbytes));
- continue; /* Interrupted */
- }
-
- if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
- {
- if (readbytes == (size_t) -1)
- my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
- my_filename(Filedes),my_errno);
- else if (MyFlags & (MY_NABP | MY_FNABP))
- my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
- my_filename(Filedes),my_errno);
- }
- if (readbytes == (size_t) -1 || (MyFlags & (MY_FNABP | MY_NABP)))
- DBUG_RETURN(MY_FILE_ERROR); /* Return with error */
- }
- if (MyFlags & (MY_NABP | MY_FNABP))
- DBUG_RETURN(0); /* Read went ok; Return 0 */
- DBUG_RETURN(readbytes); /* purecov: inspected */
- }
-} /* my_pread */
-
-
-/*
- Write a chunk of bytes to a file at a given position
-
- SYNOPSIOS
- my_pwrite()
- Filedes File decsriptor
- Buffer Buffer to write data from
- Count Number of bytes to write
- offset Position to write to
- MyFlags Flags
-
- NOTES
- This differs from the normal pwrite() call in that we don't care
- to set the position in the file back to the original position
- if the system doesn't support pwrite()
-
- RETURN
- (size_t) -1 Error
- # Number of bytes read
-*/
-
-size_t my_pwrite(File Filedes, const uchar *Buffer, size_t Count,
- my_off_t offset, myf MyFlags)
-{
- size_t writtenbytes, written;
- uint errors;
-
- DBUG_ENTER("my_pwrite");
- DBUG_PRINT("my",("fd: %d Seek: %llu Buffer: %p Count: %lu MyFlags: %d",
- Filedes, offset, Buffer, (ulong)Count, MyFlags));
- errors= 0;
- written= 0;
-
- for (;;)
- {
-#if !defined (HAVE_PREAD) && !defined (_WIN32)
- int error;
- writtenbytes= (size_t) -1;
- mysql_mutex_lock(&my_file_info[Filedes].mutex);
- error= (lseek(Filedes, offset, MY_SEEK_SET) != (my_off_t) -1 &&
- (writtenbytes= write(Filedes, Buffer, Count)) == Count);
- mysql_mutex_unlock(&my_file_info[Filedes].mutex);
- if (error)
- break;
-#elif defined (_WIN32)
- writtenbytes= my_win_pwrite(Filedes, Buffer, Count, offset);
-#else
- writtenbytes= pwrite(Filedes, Buffer, Count, offset);
-#endif
- if(writtenbytes == Count)
- break;
- my_errno= errno;
- if (writtenbytes != (size_t) -1)
- {
- written+= writtenbytes;
- Buffer+= writtenbytes;
- Count-= writtenbytes;
- offset+= writtenbytes;
- }
- DBUG_PRINT("error",("Write only %u bytes", (uint) writtenbytes));
-#ifndef NO_BACKGROUND
-
- if (my_thread_var->abort)
- MyFlags&= ~ MY_WAIT_IF_FULL; /* End if aborted by user */
-
- if ((my_errno == ENOSPC || my_errno == EDQUOT) &&
- (MyFlags & MY_WAIT_IF_FULL))
- {
- wait_for_free_space(my_filename(Filedes), errors);
- errors++;
- continue;
- }
- if ((writtenbytes && writtenbytes != (size_t) -1) || my_errno == EINTR)
- continue; /* Retry */
-#endif
- if (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),my_errno);
- }
- DBUG_RETURN(MY_FILE_ERROR); /* Error on read */
- }
- else
- break; /* Return bytes written */
- }
- DBUG_EXECUTE_IF("check", my_seek(Filedes, -1, SEEK_SET, MYF(0)););
- if (MyFlags & (MY_NABP | MY_FNABP))
- DBUG_RETURN(0); /* Want only errors */
- DBUG_RETURN(writtenbytes+written); /* purecov: inspected */
-} /* my_pwrite */
diff --git a/dep/mysqllite/mysys/my_pthread.c b/dep/mysqllite/mysys/my_pthread.c
deleted file mode 100644
index 150bde3fb33..00000000000
--- a/dep/mysqllite/mysys/my_pthread.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 */
-
-/* Functions to get threads more portable */
-
-#define DONT_REMAP_PTHREAD_FUNCTIONS
-
-#include "mysys_priv.h"
-#include <signal.h>
-#include <m_string.h>
-#include <thr_alarm.h>
-
-#if (defined(__BSD__) || defined(_BSDI_VERSION))
-#define SCHED_POLICY SCHED_RR
-#else
-#define SCHED_POLICY SCHED_OTHER
-#endif
-
-uint thd_lib_detected= 0;
-
-/* To allow use of pthread_getspecific with two arguments */
-
-#ifdef HAVE_NONPOSIX_PTHREAD_GETSPECIFIC
-#undef pthread_getspecific
-
-void *my_pthread_getspecific_imp(pthread_key_t key)
-{
- void *value;
- if (pthread_getspecific(key,(void *) &value))
- return 0;
- return value;
-}
-#endif
-
-/*
- Some functions for RTS threads, AIX, Siemens Unix and UnixWare 7
- (and DEC OSF/1 3.2 too)
-*/
-
-int my_pthread_create_detached=1;
-
-#if defined(HAVE_NONPOSIX_SIGWAIT) || defined(HAVE_DEC_3_2_THREADS)
-
-int my_sigwait(const sigset_t *set,int *sig)
-{
- int signal=sigwait((sigset_t*) set);
- if (signal < 0)
- return errno;
- *sig=signal;
- return 0;
-}
-#endif
-
-/* localtime_r for SCO 3.2V4.2 */
-
-#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
-
-extern mysql_mutex_t LOCK_localtime_r;
-
-#endif
-
-#if !defined(HAVE_LOCALTIME_R)
-struct tm *localtime_r(const time_t *clock, struct tm *res)
-{
- struct tm *tmp;
- mysql_mutex_lock(&LOCK_localtime_r);
- tmp=localtime(clock);
- *res= *tmp;
- mysql_mutex_unlock(&LOCK_localtime_r);
- return res;
-}
-#endif
-
-#if !defined(HAVE_GMTIME_R)
-/*
- Reentrant version of standard gmtime() function.
- Needed on some systems which don't implement it.
-*/
-
-struct tm *gmtime_r(const time_t *clock, struct tm *res)
-{
- struct tm *tmp;
- mysql_mutex_lock(&LOCK_localtime_r);
- tmp= gmtime(clock);
- *res= *tmp;
- mysql_mutex_unlock(&LOCK_localtime_r);
- return res;
-}
-#endif
-
-/****************************************************************************
-** Replacement of sigwait if the system doesn't have one (like BSDI 3.0)
-**
-** Note:
-** This version of sigwait() is assumed to called in a loop so the signalmask
-** is permanently modified to reflect the signal set. This is done to get
-** a much faster implementation.
-**
-** This implementation isn't thread safe: It assumes that only one
-** thread is using sigwait.
-**
-** If one later supplies a different signal mask, all old signals that
-** was used before are unblocked and set to SIGDFL.
-**
-** Author: Gary Wisniewski <garyw@spidereye.com.au>, much modified by Monty
-****************************************************************************/
-
-#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)
-
-static sigset_t sigwait_set,rev_sigwait_set,px_recd;
-
-void px_handle_sig(int sig)
-{
- sigaddset(&px_recd, sig);
-}
-
-
-void sigwait_setup(sigset_t *set)
-{
- int i;
- struct sigaction sact,sact1;
- sigset_t unblock_mask;
-
- sact.sa_flags = 0;
- sact.sa_handler = px_handle_sig;
- memcpy(&sact.sa_mask, set, sizeof(*set)); /* handler isn't thread_safe */
- sigemptyset(&unblock_mask);
- pthread_sigmask(SIG_UNBLOCK,(sigset_t*) 0,&rev_sigwait_set);
-
- for (i = 1; i <= sizeof(sigwait_set)*8; i++)
- {
- if (sigismember(set,i))
- {
- sigdelset(&rev_sigwait_set,i);
- if (!sigismember(&sigwait_set,i))
- sigaction(i, &sact, (struct sigaction*) 0);
- }
- else
- {
- sigdelset(&px_recd,i); /* Don't handle this */
- if (sigismember(&sigwait_set,i))
- { /* Remove the old handler */
- sigaddset(&unblock_mask,i);
- sigdelset(&rev_sigwait_set,i);
- sact1.sa_flags = 0;
- sact1.sa_handler = SIG_DFL;
- sigemptyset(&sact1.sa_mask);
- sigaction(i, &sact1, 0);
- }
- }
- }
- memcpy(&sigwait_set, set, sizeof(*set));
- pthread_sigmask(SIG_BLOCK,(sigset_t*) set,(sigset_t*) 0);
- pthread_sigmask(SIG_UNBLOCK,&unblock_mask,(sigset_t*) 0);
-}
-
-
-int sigwait(sigset_t *setp, int *sigp)
-{
- if (memcmp(setp,&sigwait_set,sizeof(sigwait_set)))
- sigwait_setup(setp); /* Init or change of set */
-
- for (;;)
- {
- /*
- This is a fast, not 100% portable implementation to find the signal.
- Because the handler is blocked there should be at most 1 bit set, but
- the specification on this is somewhat shady so we use a set instead a
- single variable.
- */
-
- ulong *ptr= (ulong*) &px_recd;
- ulong *end=ptr+sizeof(px_recd)/sizeof(ulong);
-
- for ( ; ptr != end ; ptr++)
- {
- if (*ptr)
- {
- ulong set= *ptr;
- int found= (int) ((char*) ptr - (char*) &px_recd)*8+1;
- while (!(set & 1))
- {
- found++;
- set>>=1;
- }
- *sigp=found;
- sigdelset(&px_recd,found);
- return 0;
- }
- }
- sigsuspend(&rev_sigwait_set);
- }
- return 0;
-}
-#else /* !DONT_USE_SIGSUSPEND */
-
-/****************************************************************************
-** Replacement of sigwait if the system doesn't have one (like BSDI 3.0)
-**
-** Note:
-** This version of sigwait() is assumed to called in a loop so the signalmask
-** is permanently modified to reflect the signal set. This is done to get
-** a much faster implementation.
-**
-** This implementation uses a extra thread to handle the signals and one
-** must always call sigwait() with the same signal mask!
-**
-** BSDI 3.0 NOTE:
-**
-** pthread_kill() doesn't work on a thread in a select() or sleep() loop?
-** After adding the sleep to sigwait_thread, all signals are checked and
-** delivered every second. This isn't that terrible performance vice, but
-** someone should report this to BSDI and ask for a fix!
-** Another problem is that when the sleep() ends, every select() in other
-** threads are interrupted!
-****************************************************************************/
-
-static sigset_t pending_set;
-static bool inited=0;
-static pthread_cond_t COND_sigwait;
-static pthread_mutex_t LOCK_sigwait;
-
-
-void sigwait_handle_sig(int sig)
-{
- pthread_mutex_lock(&LOCK_sigwait);
- sigaddset(&pending_set, sig);
- pthread_cond_signal(&COND_sigwait); /* inform sigwait() about signal */
- pthread_mutex_unlock(&LOCK_sigwait);
-}
-
-void *sigwait_thread(void *set_arg)
-{
- sigset_t *set=(sigset_t*) set_arg;
-
- int i;
- struct sigaction sact;
- sact.sa_flags = 0;
- sact.sa_handler = sigwait_handle_sig;
- memcpy(&sact.sa_mask, set, sizeof(*set)); /* handler isn't thread_safe */
- sigemptyset(&pending_set);
-
- for (i = 1; i <= sizeof(pending_set)*8; i++)
- {
- if (sigismember(set,i))
- {
- sigaction(i, &sact, (struct sigaction*) 0);
- }
- }
- /* Ensure that init_thr_alarm() is called */
- DBUG_ASSERT(thr_client_alarm);
- sigaddset(set, thr_client_alarm);
- pthread_sigmask(SIG_UNBLOCK,(sigset_t*) set,(sigset_t*) 0);
- alarm_thread=pthread_self(); /* For thr_alarm */
-
- for (;;)
- { /* Wait for signals */
-#ifdef HAVE_NOT_BROKEN_SELECT
- fd_set fd;
- FD_ZERO(&fd);
- select(0,&fd,0,0,0);
-#else
- sleep(1); /* Because of broken BSDI */
-#endif
- }
-}
-
-
-int sigwait(sigset_t *setp, int *sigp)
-{
- if (!inited)
- {
- pthread_attr_t thr_attr;
- pthread_t sigwait_thread_id;
- inited=1;
- sigemptyset(&pending_set);
- pthread_mutex_init(&LOCK_sigwait, MY_MUTEX_INIT_FAST);
- pthread_cond_init(&COND_sigwait, NULL);
-
- pthread_attr_init(&thr_attr);
- pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);
- pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
- pthread_attr_setstacksize(&thr_attr,8196);
- pthread_create(&sigwait_thread_id, &thr_attr, sigwait_thread, setp);
- pthread_attr_destroy(&thr_attr);
- }
-
- pthread_mutex_lock(&LOCK_sigwait);
- for (;;)
- {
- ulong *ptr= (ulong*) &pending_set;
- ulong *end=ptr+sizeof(pending_set)/sizeof(ulong);
-
- for ( ; ptr != end ; ptr++)
- {
- if (*ptr)
- {
- ulong set= *ptr;
- int found= (int) ((char*) ptr - (char*) &pending_set)*8+1;
- while (!(set & 1))
- {
- found++;
- set>>=1;
- }
- *sigp=found;
- sigdelset(&pending_set,found);
- pthread_mutex_unlock(&LOCK_sigwait);
- return 0;
- }
- }
- pthread_cond_wait(&COND_sigwait, &LOCK_sigwait);
- }
- return 0;
-}
-
-#endif /* DONT_USE_SIGSUSPEND */
-#endif /* HAVE_SIGWAIT */
-
-
-/****************************************************************************
- The following functions fixes that all pthread functions should work
- according to latest posix standard
-****************************************************************************/
-
-/* Undefined wrappers set my_pthread.h so that we call os functions */
-#undef pthread_mutex_init
-#undef pthread_mutex_lock
-#undef pthread_mutex_unlock
-#undef pthread_mutex_destroy
-#undef pthread_mutex_wait
-#undef pthread_mutex_timedwait
-#undef pthread_mutex_trylock
-#undef pthread_mutex_t
-#undef pthread_cond_init
-#undef pthread_cond_wait
-#undef pthread_cond_timedwait
-#undef pthread_cond_t
-#undef pthread_attr_getstacksize
-
-/*****************************************************************************
-** Patches for AIX and DEC OSF/1 3.2
-*****************************************************************************/
-
-#if defined(HAVE_NONPOSIX_PTHREAD_MUTEX_INIT)
-
-#include <netdb.h>
-
-int my_pthread_mutex_init(pthread_mutex_t *mp, const pthread_mutexattr_t *attr)
-{
- int error;
- if (!attr)
- error=pthread_mutex_init(mp,pthread_mutexattr_default);
- else
- error=pthread_mutex_init(mp,*attr);
- return error;
-}
-
-int my_pthread_cond_init(pthread_cond_t *mp, const pthread_condattr_t *attr)
-{
- int error;
- if (!attr)
- error=pthread_cond_init(mp,pthread_condattr_default);
- else
- error=pthread_cond_init(mp,*attr);
- return error;
-}
-
-#endif
-
-
-/*****************************************************************************
- Patches for HPUX
- We need these because the pthread_mutex.. code returns -1 on error,
- instead of the error code.
-
- Note that currently we only remap pthread_ functions used by MySQL.
- If we are depending on the value for some other pthread_xxx functions,
- this has to be added here.
-****************************************************************************/
-
-#if defined(HPUX10) || defined(HAVE_BROKEN_PTHREAD_COND_TIMEDWAIT)
-
-int my_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
- struct timespec *abstime)
-{
- int error=pthread_cond_timedwait(cond, mutex, abstime);
- if (error == -1) /* Safety if the lib is fixed */
- {
- if (!(error=errno))
- error= ETIMEDOUT; /* Can happen on HPUX */
- }
- if (error == EAGAIN) /* Correct errno to Posix */
- error= ETIMEDOUT;
- return error;
-}
-#endif
-
-#if defined(HPUX10)
-
-void my_pthread_attr_getstacksize(pthread_attr_t *connection_attrib,
- size_t *stack_size)
-{
- *stack_size= pthread_attr_getstacksize(*connection_attrib);
-}
-#endif
-
-
-#ifdef HAVE_POSIX1003_4a_MUTEX
-/*
- In HP-UX-10.20 and other old Posix 1003.4a Draft 4 implementations
- pthread_mutex_trylock returns 1 on success, not 0 like
- pthread_mutex_lock
-
- From the HP-UX-10.20 man page:
- RETURN VALUES
- If the function fails, errno may be set to one of the following
- values:
- Return | Error | Description
- _______|__________|_________________________________________
- 1 | | Successful completion.
- 0 | | The mutex is locked; therefore, it was
- | | not acquired.
- -1 | [EINVAL] | The value specified by mutex is invalid.
-
-*/
-
-/*
- Convert pthread_mutex_trylock to return values according to latest POSIX
-
- RETURN VALUES
- 0 If we are able successfully lock the mutex.
- EBUSY Mutex was locked by another thread
- # Other error number returned by pthread_mutex_trylock()
- (Not likely)
-*/
-
-int my_pthread_mutex_trylock(pthread_mutex_t *mutex)
-{
- int error= pthread_mutex_trylock(mutex);
- if (error == 1)
- return 0; /* Got lock on mutex */
- if (error == 0) /* Someon else is locking mutex */
- return EBUSY;
- if (error == -1) /* Safety if the lib is fixed */
- error= errno; /* Probably invalid parameter */
- return error;
-}
-#endif /* HAVE_POSIX1003_4a_MUTEX */
-
-/* Some help functions */
-
-int pthread_dummy(int ret)
-{
- return ret;
-}
diff --git a/dep/mysqllite/mysys/my_quick.c b/dep/mysqllite/mysys/my_quick.c
deleted file mode 100644
index b93e7e17224..00000000000
--- a/dep/mysqllite/mysys/my_quick.c
+++ /dev/null
@@ -1,81 +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 */
-
-/* Quicker interface to read & write. Used with my_nosys.h */
-
-#include "mysys_priv.h"
-#include "my_nosys.h"
-
-
-#ifdef _WIN32
-extern size_t my_win_read(File Filedes,uchar *Buffer,size_t Count);
-#endif
-
-size_t my_quick_read(File Filedes,uchar *Buffer,size_t Count,myf MyFlags)
-{
- size_t readbytes;
-#ifdef _WIN32
- readbytes= my_win_read(Filedes, Buffer, Count);
-#else
- readbytes= read(Filedes, Buffer, Count);
-#endif
- if(readbytes != Count)
- {
-#ifndef DBUG_OFF
- if ((readbytes == 0 || readbytes == (size_t) -1) && errno == EINTR)
- {
- DBUG_PRINT("error", ("my_quick_read() was interrupted and returned %d"
- ". This function does not retry the read!",
- (int) readbytes));
- }
-#endif
- my_errno=errno;
- return readbytes;
- }
- return (MyFlags & (MY_NABP | MY_FNABP)) ? 0 : readbytes;
-}
-
-
-
-size_t my_quick_write(File Filedes, const uchar *Buffer, size_t Count)
-{
-#ifdef _WIN32
- return my_win_write(Filedes, Buffer, Count);
-#else
-
-#ifndef DBUG_OFF
- size_t writtenbytes;
-#endif
-
- if ((
-#ifndef DBUG_OFF
- writtenbytes =
-#endif
- (size_t) write(Filedes,Buffer,Count)) != Count)
- {
-#ifndef DBUG_OFF
- if ((writtenbytes == 0 || writtenbytes == (size_t) -1) && errno == EINTR)
- {
- DBUG_PRINT("error", ("my_quick_write() was interrupted and returned %d"
- ". This function does not retry the write!",
- (int) writtenbytes));
- }
-#endif
- my_errno=errno;
- return (size_t) -1;
- }
- return 0;
-#endif
-}
diff --git a/dep/mysqllite/mysys/my_rdtsc.c b/dep/mysqllite/mysys/my_rdtsc.c
deleted file mode 100644
index 2afe3ec31dd..00000000000
--- a/dep/mysqllite/mysys/my_rdtsc.c
+++ /dev/null
@@ -1,962 +0,0 @@
-/* Copyright (C) 2008-2010 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 */
-
-/*
- rdtsc3 -- multi-platform timer code
- pgulutzan@mysql.com, 2005-08-29
- modified 2008-11-02
-
- Functions:
-
- my_timer_cycles ulonglong cycles
- my_timer_nanoseconds ulonglong nanoseconds
- my_timer_microseconds ulonglong "microseconds"
- my_timer_milliseconds ulonglong milliseconds
- my_timer_ticks ulonglong ticks
- my_timer_init initialization / test
-
- We'll call the first 5 functions (the ones that return
- a ulonglong) "my_timer_xxx" functions.
- Each my_timer_xxx function returns a 64-bit timing value
- since an arbitrary 'epoch' start. Since the only purpose
- is to determine elapsed times, wall-clock time-of-day
- is not known and not relevant.
-
- The my_timer_init function is necessary for initializing.
- It returns information (underlying routine name,
- frequency, resolution, overhead) about all my_timer_xxx
- functions. A program should call my_timer_init once,
- use the information to decide what my_timer_xxx function
- to use, and subsequently call that function by function
- pointer.
-
- A typical use would be:
- my_timer_init() ... once, at program start
- ...
- time1= my_timer_xxx() ... time before start
- [code that's timed]
- time2= my_timer_xxx() ... time after end
- elapsed_time= (time2 - time1) - overhead
-*/
-
-#include "my_global.h"
-#include "my_rdtsc.h"
-
-#if defined(_WIN32)
-#include <stdio.h>
-#include "windows.h"
-#else
-#include <stdio.h>
-#endif
-
-#if !defined(_WIN32)
-#if TIME_WITH_SYS_TIME
-#include <sys/time.h>
-#include <time.h> /* for clock_gettime */
-#else
-#if HAVE_SYS_TIME_H
-#include <sys/time.h>
-#elif defined(HAVE_TIME_H)
-#include <time.h>
-#endif
-#endif
-#endif
-
-#if defined(HAVE_ASM_MSR_H) && defined(HAVE_RDTSCLL)
-#include <asm/msr.h> /* for rdtscll */
-#endif
-
-#if defined(HAVE_SYS_TIMEB_H) && defined(HAVE_FTIME)
-#include <sys/timeb.h> /* for ftime */
-#endif
-
-#if defined(HAVE_SYS_TIMES_H) && defined(HAVE_TIMES)
-#include <sys/times.h> /* for times */
-#endif
-
-#if defined(__INTEL_COMPILER) && defined(__ia64__) && defined(HAVE_IA64INTRIN_H)
-#include <ia64intrin.h> /* for __GetReg */
-#endif
-
-#if defined(__APPLE__) && defined(__MACH__)
-#include <mach/mach_time.h>
-#endif
-
-#if defined(__SUNPRO_CC) && defined(__sparcv9) && defined(_LP64) && !defined(__SunOS_5_7)
-extern "C" ulonglong my_timer_cycles_il_sparc64();
-#elif defined(__SUNPRO_CC) && defined(_ILP32) && !defined(__SunOS_5_7)
-extern "C" ulonglong my_timer_cycles_il_sparc32();
-#elif defined(__SUNPRO_CC) && defined(__i386) && defined(_ILP32)
-extern "C" ulonglong my_timer_cycles_il_i386();
-#elif defined(__SUNPRO_CC) && defined(__x86_64) && defined(_LP64)
-extern "C" ulonglong my_timer_cycles_il_x86_64();
-#elif defined(__SUNPRO_C) && defined(__sparcv9) && defined(_LP64) && !defined(__SunOS_5_7)
-ulonglong my_timer_cycles_il_sparc64();
-#elif defined(__SUNPRO_C) && defined(_ILP32) && !defined(__SunOS_5_7)
-ulonglong my_timer_cycles_il_sparc32();
-#elif defined(__SUNPRO_C) && defined(__i386) && defined(_ILP32)
-ulonglong my_timer_cycles_il_i386();
-#elif defined(__SUNPRO_C) && defined(__x86_64) && defined(_LP64)
-ulonglong my_timer_cycles_il_x86_64();
-#endif
-
-#if defined(__INTEL_COMPILER)
-/*
- icc warning #1011 is:
- missing return statement at end of non-void function
-*/
-#pragma warning (disable:1011)
-#endif
-
-/*
- For cycles, we depend on RDTSC for x86 platforms,
- or on time buffer (which is not really a cycle count
- but a separate counter with less than nanosecond
- resolution) for most PowerPC platforms, or on
- gethrtime which is okay for hpux and solaris, or on
- clock_gettime(CLOCK_SGI_CYCLE) for Irix platforms,
- or on read_real_time for aix platforms. There is
- nothing for Alpha platforms, they would be tricky.
-*/
-
-ulonglong my_timer_cycles(void)
-{
-#if defined(__GNUC__) && defined(__i386__)
- /* This works much better if compiled with "gcc -O3". */
- ulonglong result;
- __asm__ __volatile__ ("rdtsc" : "=A" (result));
- return result;
-#elif defined(__SUNPRO_C) && defined(__i386)
- __asm("rdtsc");
-#elif defined(__GNUC__) && defined(__x86_64__)
- ulonglong result;
- __asm__ __volatile__ ("rdtsc\n\t" \
- "shlq $32,%%rdx\n\t" \
- "orq %%rdx,%%rax"
- : "=a" (result) :: "%edx");
- return result;
-#elif defined(HAVE_ASM_MSR_H) && defined(HAVE_RDTSCLL)
- {
- ulonglong result;
- rdtscll(result);
- return result;
- }
-#elif defined(_WIN32) && defined(_M_IX86)
- __asm {rdtsc};
-#elif defined(_WIN64) && defined(_M_X64)
- /* For 64-bit Windows: unsigned __int64 __rdtsc(); */
- return __rdtsc();
-#elif defined(__INTEL_COMPILER) && defined(__ia64__) && defined(HAVE_IA64INTRIN_H)
- return (ulonglong) __getReg(_IA64_REG_AR_ITC); /* (3116) */
-#elif defined(__GNUC__) && defined(__ia64__)
- {
- ulonglong result;
- __asm __volatile__ ("mov %0=ar.itc" : "=r" (result));
- return result;
- }
-#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__POWERPC__) || (defined(_POWER) && defined(_AIX52))) && (defined(__64BIT__) || defined(_ARCH_PPC64))
- {
- ulonglong result;
- __asm __volatile__ ("mftb %0" : "=r" (result));
- return result;
- }
-#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__POWERPC__) || (defined(_POWER) && defined(_AIX52))) && (!defined(__64BIT__) && !defined(_ARCH_PPC64))
- {
- /*
- mftbu means "move from time-buffer-upper to result".
- The loop is saying: x1=upper, x2=lower, x3=upper,
- if x1!=x3 there was an overflow so repeat.
- */
- unsigned int x1, x2, x3;
- ulonglong result;
- for (;;)
- {
- __asm __volatile__ ( "mftbu %0" : "=r"(x1) );
- __asm __volatile__ ( "mftb %0" : "=r"(x2) );
- __asm __volatile__ ( "mftbu %0" : "=r"(x3) );
- if (x1 == x3) break;
- }
- result = x1;
- return ( result << 32 ) | x2;
- }
-#elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(__sparcv9) && defined(_LP64) && !defined(__SunOS_5_7)
- return (my_timer_cycles_il_sparc64());
-#elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(_ILP32) && !defined(__SunOS_5_7)
- return (my_timer_cycles_il_sparc32());
-#elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(__i386) && defined(_ILP32)
- /* This is probably redundant for __SUNPRO_C. */
- return (my_timer_cycles_il_i386());
-#elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(__x86_64) && defined(_LP64)
- return (my_timer_cycles_il_x86_64());
-#elif defined(__GNUC__) && defined(__sparcv9) && defined(_LP64) && (__GNUC__>2)
- {
- ulonglong result;
- __asm __volatile__ ("rd %%tick,%0" : "=r" (result));
- return result;
- }
-#elif defined(__GNUC__) && defined(__sparc__) && !defined(_LP64) && (__GNUC__>2)
- {
- union {
- ulonglong wholeresult;
- struct {
- ulong high;
- ulong low;
- } splitresult;
- } result;
- __asm __volatile__ ("rd %%tick,%1; srlx %1,32,%0" : "=r" (result.splitresult.high), "=r" (result.splitresult.low));
- return result.wholeresult;
- }
-#elif defined(__sgi) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_SGI_CYCLE)
- {
- struct timespec tp;
- clock_gettime(CLOCK_SGI_CYCLE, &tp);
- return (ulonglong) tp.tv_sec * 1000000000 + (ulonglong) tp.tv_nsec;
- }
-#elif defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME)
- /* gethrtime may appear as either cycle or nanosecond counter */
- return (ulonglong) gethrtime();
-#else
- return 0;
-#endif
-}
-
-#if defined(__INTEL_COMPILER)
-/* re-enable warning#1011 which was only for my_timer_cycles() */
-/* There may be an icc bug which means we must leave disabled. */
-#pragma warning (default:1011)
-#endif
-
-/*
- For nanoseconds, most platforms have nothing available that
- (a) doesn't require bringing in a 40-kb librt.so library
- (b) really has nanosecond resolution.
-*/
-
-ulonglong my_timer_nanoseconds(void)
-{
-#if defined(HAVE_READ_REAL_TIME)
- {
- timebasestruct_t tr;
- read_real_time(&tr, TIMEBASE_SZ);
- return (ulonglong) tr.tb_high * 1000000000 + (ulonglong) tr.tb_low;
- }
-#elif defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME)
- /* SunOS 5.10+, Solaris, HP-UX: hrtime_t gethrtime(void) */
- return (ulonglong) gethrtime();
-#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)
- {
- struct timespec tp;
- clock_gettime(CLOCK_REALTIME, &tp);
- return (ulonglong) tp.tv_sec * 1000000000 + (ulonglong) tp.tv_nsec;
- }
-#elif defined(__APPLE__) && defined(__MACH__)
- {
- ulonglong tm;
- static mach_timebase_info_data_t timebase_info= {0,0};
- if (timebase_info.denom == 0)
- (void) mach_timebase_info(&timebase_info);
- tm= mach_absolute_time();
- return (tm * timebase_info.numer) / timebase_info.denom;
- }
-#else
- return 0;
-#endif
-}
-
-/*
- For microseconds, gettimeofday() is available on
- almost all platforms. On Windows we use
- QueryPerformanceCounter which will usually tick over
- 3.5 million times per second, and we don't throw
- away the extra precision. (On Windows Server 2003
- the frequency is same as the cycle frequency.)
-*/
-
-ulonglong my_timer_microseconds(void)
-{
-#if defined(HAVE_GETTIMEOFDAY)
- {
- static ulonglong last_value= 0;
- struct timeval tv;
- if (gettimeofday(&tv, NULL) == 0)
- last_value= (ulonglong) tv.tv_sec * 1000000 + (ulonglong) tv.tv_usec;
- else
- {
- /*
- There are reports that gettimeofday(2) can have intermittent failures
- on some platform, see for example Bug#36819.
- We are not trying again or looping, just returning the best value possible
- under the circumstances ...
- */
- last_value++;
- }
- return last_value;
- }
-#elif defined(_WIN32)
- {
- /* QueryPerformanceCounter usually works with about 1/3 microsecond. */
- LARGE_INTEGER t_cnt;
-
- QueryPerformanceCounter(&t_cnt);
- return (ulonglong) t_cnt.QuadPart;
- }
-#else
- return 0;
-#endif
-}
-
-/*
- For milliseconds, we use ftime() if it's supported
- or time()*1000 if it's not. With modern versions of
- Windows and with HP Itanium, resolution is 10-15
- milliseconds.
-*/
-
-ulonglong my_timer_milliseconds(void)
-{
-#if defined(HAVE_SYS_TIMEB_H) && defined(HAVE_FTIME)
- /* ftime() is obsolete but maybe the platform is old */
- struct timeb ft;
- ftime(&ft);
- return (ulonglong)ft.time * 1000 + (ulonglong)ft.millitm;
-#elif defined(HAVE_TIME)
- return (ulonglong) time(NULL) * 1000;
-#elif defined(_WIN32)
- FILETIME ft;
- GetSystemTimeAsFileTime( &ft );
- return ((ulonglong)ft.dwLowDateTime +
- (((ulonglong)ft.dwHighDateTime) << 32))/10000;
-#else
- return 0;
-#endif
-}
-
-/*
- For ticks, which we handle with times(), the frequency
- is usually 100/second and the overhead is surprisingly
- bad, sometimes even worse than gettimeofday's overhead.
-*/
-
-ulonglong my_timer_ticks(void)
-{
-#if defined(HAVE_SYS_TIMES_H) && defined(HAVE_TIMES)
- {
- struct tms times_buf;
- return (ulonglong) times(&times_buf);
- }
-#elif defined(_WIN32)
- return (ulonglong) GetTickCount();
-#else
- return 0;
-#endif
-}
-
-/*
- The my_timer_init() function and its sub-functions
- have several loops which call timers. If there's
- something wrong with a timer -- which has never
- happened in tests -- we want the loop to end after
- an arbitrary number of iterations, and my_timer_info
- will show a discouraging result. The arbitrary
- number is 1,000,000.
-*/
-#define MY_TIMER_ITERATIONS 1000000
-
-/*
- Calculate overhead. Called from my_timer_init().
- Usually best_timer_overhead = cycles.overhead or
- nanoseconds.overhead, so returned amount is in
- cycles or nanoseconds. We repeat the calculation
- ten times, so that we can disregard effects of
- caching or interrupts. Result is quite consistent
- for cycles, at least. But remember it's a minimum.
-*/
-
-static void my_timer_init_overhead(ulonglong *overhead,
- ulonglong (*cycle_timer)(void),
- ulonglong (*this_timer)(void),
- ulonglong best_timer_overhead)
-{
- ulonglong time1, time2;
- int i;
-
- /* *overhead, least of 20 calculations - cycles.overhead */
- for (i= 0, *overhead= 1000000000; i < 20; ++i)
- {
- time1= cycle_timer();
- this_timer(); /* rather than 'time_tmp= timer();' */
- time2= cycle_timer() - time1;
- if (*overhead > time2)
- *overhead= time2;
- }
- *overhead-= best_timer_overhead;
-}
-
-/*
- Calculate Resolution. Called from my_timer_init().
- If a timer goes up by jumps, e.g. 1050, 1075, 1100, ...
- then the best resolution is the minimum jump, e.g. 25.
- If it's always divisible by 1000 then it's just a
- result of multiplication of a lower-precision timer
- result, e.g. nanoseconds are often microseconds * 1000.
- If the minimum jump is less than an arbitrary passed
- figure (a guess based on maximum overhead * 2), ignore.
- Usually we end up with nanoseconds = 1 because it's too
- hard to detect anything <= 100 nanoseconds.
- Often GetTickCount() has resolution = 15.
- We don't check with ticks because they take too long.
-*/
-static ulonglong my_timer_init_resolution(ulonglong (*this_timer)(void),
- ulonglong overhead_times_2)
-{
- ulonglong time1, time2;
- ulonglong best_jump;
- int i, jumps, divisible_by_1000, divisible_by_1000000;
-
- divisible_by_1000= divisible_by_1000000= 0;
- best_jump= 1000000;
- for (i= jumps= 0; jumps < 3 && i < MY_TIMER_ITERATIONS * 10; ++i)
- {
- time1= this_timer();
- time2= this_timer();
- time2-= time1;
- if (time2)
- {
- ++jumps;
- if (!(time2 % 1000))
- {
- ++divisible_by_1000;
- if (!(time2 % 1000000))
- ++divisible_by_1000000;
- }
- if (best_jump > time2)
- best_jump= time2;
- /* For milliseconds, one jump is enough. */
- if (overhead_times_2 == 0)
- break;
- }
- }
- if (jumps == 3)
- {
- if (jumps == divisible_by_1000000)
- return 1000000;
- if (jumps == divisible_by_1000)
- return 1000;
- }
- if (best_jump > overhead_times_2)
- return best_jump;
- return 1;
-}
-
-/*
- Calculate cycle frequency by seeing how many cycles pass
- in a 200-microsecond period. I tried with 10-microsecond
- periods originally, and the result was often very wrong.
-*/
-
-static ulonglong my_timer_init_frequency(MY_TIMER_INFO *mti)
-{
- int i;
- ulonglong time1, time2, time3, time4;
- time1= my_timer_cycles();
- time2= my_timer_microseconds();
- time3= time2; /* Avoids a Microsoft/IBM compiler warning */
- for (i= 0; i < MY_TIMER_ITERATIONS; ++i)
- {
- time3= my_timer_microseconds();
- if (time3 - time2 > 200) break;
- }
- time4= my_timer_cycles() - mti->cycles.overhead;
- time4-= mti->microseconds.overhead;
- return (mti->microseconds.frequency * (time4 - time1)) / (time3 - time2);
-}
-
-/*
- Call my_timer_init before the first call to my_timer_xxx().
- If something must be initialized, it happens here.
- Set: what routine is being used e.g. "asm_x86"
- Set: function, overhead, actual frequency, resolution.
-*/
-
-void my_timer_init(MY_TIMER_INFO *mti)
-{
- ulonglong (*best_timer)(void);
- ulonglong best_timer_overhead;
- ulonglong time1, time2;
- int i;
-
- /* cycles */
- mti->cycles.frequency= 1000000000;
-#if defined(__GNUC__) && defined(__i386__)
- mti->cycles.routine= MY_TIMER_ROUTINE_ASM_X86;
-#elif defined(__SUNPRO_C) && defined(__i386)
- mti->cycles.routine= MY_TIMER_ROUTINE_ASM_X86;
-#elif defined(__GNUC__) && defined(__x86_64__)
- mti->cycles.routine= MY_TIMER_ROUTINE_ASM_X86_64;
-#elif defined(HAVE_ASM_MSR_H) && defined(HAVE_RDTSCLL)
- mti->cycles.routine= MY_TIMER_ROUTINE_RDTSCLL;
-#elif defined(_WIN32) && defined(_M_IX86)
- mti->cycles.routine= MY_TIMER_ROUTINE_ASM_X86_WIN;
-#elif defined(_WIN64) && defined(_M_X64)
- mti->cycles.routine= MY_TIMER_ROUTINE_RDTSC;
-#elif defined(__INTEL_COMPILER) && defined(__ia64__) && defined(HAVE_IA64INTRIN_H)
- mti->cycles.routine= MY_TIMER_ROUTINE_ASM_IA64;
-#elif defined(__GNUC__) && defined(__ia64__)
- mti->cycles.routine= MY_TIMER_ROUTINE_ASM_IA64;
-#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__POWERPC__) || (defined(_POWER) && defined(_AIX52))) && (defined(__64BIT__) || defined(_ARCH_PPC64))
- mti->cycles.routine= MY_TIMER_ROUTINE_ASM_PPC64;
-#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__POWERPC__) || (defined(_POWER) && defined(_AIX52))) && (!defined(__64BIT__) && !defined(_ARCH_PPC64))
- mti->cycles.routine= MY_TIMER_ROUTINE_ASM_PPC;
-#elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(__sparcv9) && defined(_LP64) && !defined(__SunOS_5_7)
- mti->cycles.routine= MY_TIMER_ROUTINE_ASM_SUNPRO_SPARC64;
-#elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(_ILP32) && !defined(__SunOS_5_7)
- mti->cycles.routine= MY_TIMER_ROUTINE_ASM_SUNPRO_SPARC32;
-#elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(__i386) && defined(_ILP32)
- mti->cycles.routine= MY_TIMER_ROUTINE_ASM_SUNPRO_I386;
-#elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(__x86_64) && defined(_LP64)
- mti->cycles.routine= MY_TIMER_ROUTINE_ASM_SUNPRO_X86_64;
-#elif defined(__GNUC__) && defined(__sparcv9) && defined(_LP64) && (__GNUC__>2)
- mti->cycles.routine= MY_TIMER_ROUTINE_ASM_GCC_SPARC64;
-#elif defined(__GNUC__) && defined(__sparc__) && !defined(_LP64) && (__GNUC__>2)
- mti->cycles.routine= MY_TIMER_ROUTINE_ASM_GCC_SPARC32;
-#elif defined(__sgi) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_SGI_CYCLE)
- mti->cycles.routine= MY_TIMER_ROUTINE_SGI_CYCLE;
-#elif defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME)
- mti->cycles.routine= MY_TIMER_ROUTINE_GETHRTIME;
-#else
- mti->cycles.routine= 0;
-#endif
-
- if (!mti->cycles.routine || !my_timer_cycles())
- {
- mti->cycles.routine= 0;
- mti->cycles.resolution= 0;
- mti->cycles.frequency= 0;
- mti->cycles.overhead= 0;
- }
-
- /* nanoseconds */
- mti->nanoseconds.frequency= 1000000000; /* initial assumption */
-#if defined(HAVE_READ_REAL_TIME)
- mti->nanoseconds.routine= MY_TIMER_ROUTINE_READ_REAL_TIME;
-#elif defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME)
- mti->nanoseconds.routine= MY_TIMER_ROUTINE_GETHRTIME;
-#elif defined(HAVE_CLOCK_GETTIME)
- mti->nanoseconds.routine= MY_TIMER_ROUTINE_CLOCK_GETTIME;
-#elif defined(__APPLE__) && defined(__MACH__)
- mti->nanoseconds.routine= MY_TIMER_ROUTINE_MACH_ABSOLUTE_TIME;
-#else
- mti->nanoseconds.routine= 0;
-#endif
- if (!mti->nanoseconds.routine || !my_timer_nanoseconds())
- {
- mti->nanoseconds.routine= 0;
- mti->nanoseconds.resolution= 0;
- mti->nanoseconds.frequency= 0;
- mti->nanoseconds.overhead= 0;
- }
-
- /* microseconds */
- mti->microseconds.frequency= 1000000; /* initial assumption */
-#if defined(HAVE_GETTIMEOFDAY)
- mti->microseconds.routine= MY_TIMER_ROUTINE_GETTIMEOFDAY;
-#elif defined(_WIN32)
- {
- LARGE_INTEGER li;
- /* Windows: typical frequency = 3579545, actually 1/3 microsecond. */
- if (!QueryPerformanceFrequency(&li))
- mti->microseconds.routine= 0;
- else
- {
- mti->microseconds.frequency= li.QuadPart;
- mti->microseconds.routine= MY_TIMER_ROUTINE_QUERYPERFORMANCECOUNTER;
- }
- }
-#else
- mti->microseconds.routine= 0;
-#endif
- if (!mti->microseconds.routine || !my_timer_microseconds())
- {
- mti->microseconds.routine= 0;
- mti->microseconds.resolution= 0;
- mti->microseconds.frequency= 0;
- mti->microseconds.overhead= 0;
- }
-
- /* milliseconds */
- mti->milliseconds.frequency= 1000; /* initial assumption */
-#if defined(HAVE_SYS_TIMEB_H) && defined(HAVE_FTIME)
- mti->milliseconds.routine= MY_TIMER_ROUTINE_FTIME;
-#elif defined(_WIN32)
- mti->milliseconds.routine= MY_TIMER_ROUTINE_GETSYSTEMTIMEASFILETIME;
-#elif defined(HAVE_TIME)
- mti->milliseconds.routine= MY_TIMER_ROUTINE_TIME;
-#else
- mti->milliseconds.routine= 0;
-#endif
- if (!mti->milliseconds.routine || !my_timer_milliseconds())
- {
- mti->milliseconds.routine= 0;
- mti->milliseconds.resolution= 0;
- mti->milliseconds.frequency= 0;
- mti->milliseconds.overhead= 0;
- }
-
- /* ticks */
- mti->ticks.frequency= 100; /* permanent assumption */
-#if defined(HAVE_SYS_TIMES_H) && defined(HAVE_TIMES)
- mti->ticks.routine= MY_TIMER_ROUTINE_TIMES;
-#elif defined(_WIN32)
- mti->ticks.routine= MY_TIMER_ROUTINE_GETTICKCOUNT;
-#else
- mti->ticks.routine= 0;
-#endif
- if (!mti->ticks.routine || !my_timer_ticks())
- {
- mti->ticks.routine= 0;
- mti->ticks.resolution= 0;
- mti->ticks.frequency= 0;
- mti->ticks.overhead= 0;
- }
-
- /*
- Calculate overhead in terms of the timer that
- gives the best resolution: cycles or nanoseconds.
- I doubt it ever will be as bad as microseconds.
- */
- if (mti->cycles.routine)
- best_timer= &my_timer_cycles;
- else
- {
- if (mti->nanoseconds.routine)
- {
- best_timer= &my_timer_nanoseconds;
- }
- else
- best_timer= &my_timer_microseconds;
- }
-
- /* best_timer_overhead = least of 20 calculations */
- for (i= 0, best_timer_overhead= 1000000000; i < 20; ++i)
- {
- time1= best_timer();
- time2= best_timer() - time1;
- if (best_timer_overhead > time2)
- best_timer_overhead= time2;
- }
- if (mti->cycles.routine)
- my_timer_init_overhead(&mti->cycles.overhead,
- best_timer,
- &my_timer_cycles,
- best_timer_overhead);
- if (mti->nanoseconds.routine)
- my_timer_init_overhead(&mti->nanoseconds.overhead,
- best_timer,
- &my_timer_nanoseconds,
- best_timer_overhead);
- if (mti->microseconds.routine)
- my_timer_init_overhead(&mti->microseconds.overhead,
- best_timer,
- &my_timer_microseconds,
- best_timer_overhead);
- if (mti->milliseconds.routine)
- my_timer_init_overhead(&mti->milliseconds.overhead,
- best_timer,
- &my_timer_milliseconds,
- best_timer_overhead);
- if (mti->ticks.routine)
- my_timer_init_overhead(&mti->ticks.overhead,
- best_timer,
- &my_timer_ticks,
- best_timer_overhead);
-
-/*
- Calculate resolution for nanoseconds or microseconds
- or milliseconds, by seeing if it's always divisible
- by 1000, and by noticing how much jumping occurs.
- For ticks, just assume the resolution is 1.
-*/
- if (mti->cycles.routine)
- mti->cycles.resolution= 1;
- if (mti->nanoseconds.routine)
- mti->nanoseconds.resolution=
- my_timer_init_resolution(&my_timer_nanoseconds, 20000);
- if (mti->microseconds.routine)
- mti->microseconds.resolution=
- my_timer_init_resolution(&my_timer_microseconds, 20);
- if (mti->milliseconds.routine)
- {
- if (mti->milliseconds.routine == MY_TIMER_ROUTINE_TIME)
- mti->milliseconds.resolution= 1000;
- else
- mti->milliseconds.resolution=
- my_timer_init_resolution(&my_timer_milliseconds, 0);
- }
- if (mti->ticks.routine)
- mti->ticks.resolution= 1;
-
-/*
- Calculate cycles frequency,
- if we have both a cycles routine and a microseconds routine.
- In tests, this usually results in a figure within 2% of
- what "cat /proc/cpuinfo" says.
- If the microseconds routine is QueryPerformanceCounter
- (i.e. it's Windows), and the microseconds frequency is >
- 500,000,000 (i.e. it's Windows Server so it uses RDTSC)
- and the microseconds resolution is > 100 (i.e. dreadful),
- then calculate cycles frequency = microseconds frequency.
-*/
- if (mti->cycles.routine
- && mti->microseconds.routine)
- {
- if (mti->microseconds.routine ==
- MY_TIMER_ROUTINE_QUERYPERFORMANCECOUNTER
- && mti->microseconds.frequency > 500000000
- && mti->microseconds.resolution > 100)
- mti->cycles.frequency= mti->microseconds.frequency;
- else
- {
- ulonglong time1, time2;
- time1= my_timer_init_frequency(mti);
- /* Repeat once in case there was an interruption. */
- time2= my_timer_init_frequency(mti);
- if (time1 < time2) mti->cycles.frequency= time1;
- else mti->cycles.frequency= time2;
- }
- }
-
-/*
- Calculate milliseconds frequency =
- (cycles-frequency/#-of-cycles) * #-of-milliseconds,
- if we have both a milliseconds routine and a cycles
- routine.
- This will be inaccurate if milliseconds resolution > 1.
- This is probably only useful when testing new platforms.
-*/
- if (mti->milliseconds.routine
- && mti->milliseconds.resolution < 1000
- && mti->microseconds.routine
- && mti->cycles.routine)
- {
- int i;
- ulonglong time1, time2, time3, time4;
- time1= my_timer_cycles();
- time2= my_timer_milliseconds();
- time3= time2; /* Avoids a Microsoft/IBM compiler warning */
- for (i= 0; i < MY_TIMER_ITERATIONS * 1000; ++i)
- {
- time3= my_timer_milliseconds();
- if (time3 - time2 > 10) break;
- }
- time4= my_timer_cycles();
- mti->milliseconds.frequency=
- (mti->cycles.frequency * (time3 - time2)) / (time4 - time1);
- }
-
-/*
- Calculate ticks.frequency =
- (cycles-frequency/#-of-cycles * #-of-ticks,
- if we have both a ticks routine and a cycles
- routine,
- This is probably only useful when testing new platforms.
-*/
- if (mti->ticks.routine
- && mti->microseconds.routine
- && mti->cycles.routine)
- {
- int i;
- ulonglong time1, time2, time3, time4;
- time1= my_timer_cycles();
- time2= my_timer_ticks();
- time3= time2; /* Avoids a Microsoft/IBM compiler warning */
- for (i= 0; i < MY_TIMER_ITERATIONS * 1000; ++i)
- {
- time3= my_timer_ticks();
- if (time3 - time2 > 10) break;
- }
- time4= my_timer_cycles();
- mti->ticks.frequency=
- (mti->cycles.frequency * (time3 - time2)) / (time4 - time1);
- }
-}
-
-/*
- Additional Comments
- -------------------
-
- This is for timing, i.e. finding out how long a piece of code
- takes. If you want time of day matching a wall clock, the
- my_timer_xxx functions won't help you.
-
- The best timer is the one with highest frequency, lowest
- overhead, and resolution=1. The my_timer_info() routine will tell
- you at runtime which timer that is. Usually it will be
- my_timer_cycles() but be aware that, although it's best,
- it has possible flaws and dangers. Depending on platform:
- - The frequency might change. We don't test for this. It
- happens on laptops for power saving, and on blade servers
- for avoiding overheating.
- - The overhead that my_timer_init() returns is the minimum.
- In fact it could be slightly greater because of caching or
- because you call the routine by address, as recommended.
- It could be hugely greater if there's an interrupt.
- - The x86 cycle counter, RDTSC doesn't "serialize". That is,
- if there is out-of-order execution, rdtsc might be processed
- after an instruction that logically follows it.
- (We could force serialization, but that would be slower.)
- - It is possible to set a flag which renders RDTSC
- inoperative. Somebody responsible for the kernel
- of the operating system would have to make this
- decision. For the platforms we've tested with, there's
- no such problem.
- - With a multi-processor arrangement, it's possible
- to get the cycle count from one processor in
- thread X, and the cycle count from another processor
- in thread Y. They may not always be in synch.
- - You can't depend on a cycle counter being available for
- all platforms. On Alphas, the
- cycle counter is only 32-bit, so it would overflow quickly,
- so we don't bother with it. On platforms that we haven't
- tested, there might be some if/endif combination that we
- didn't expect, or some assembler routine that we didn't
- supply.
-
- The recommended way to use the timer routines is:
- 1. Somewhere near the beginning of the program, call
- my_timer_init(). This should only be necessary once,
- although you can call it again if you think that the
- frequency has changed.
- 2. Determine the best timer based on frequency, resolution,
- overhead -- all things that my_timer_init() returns.
- Preserve the address of the timer and the my_timer_into
- results in an easily-accessible place.
- 3. Instrument the code section that you're monitoring, thus:
- time1= my_timer_xxx();
- Instrumented code;
- time2= my_timer_xxx();
- elapsed_time= (time2 - time1) - overhead;
- If the timer is always on, then overhead is always there,
- so don't subtract it.
- 4. Save the elapsed time, or add it to a totaller.
- 5. When all timing processes are complete, transfer the
- saved / totalled elapsed time to permanent storage.
- Optionally you can convert cycles to microseconds at
- this point. (Don't do so every time you calculate
- elapsed_time! That would waste time and lose precision!)
- For converting cycles to microseconds, use the frequency
- that my_timer_init() returns. You'll also need to convert
- if the my_timer_microseconds() function is the Windows
- function QueryPerformanceCounter(), since that's sometimes
- a counter with precision slightly better than microseconds.
-
- Since we recommend calls by function pointer, we supply
- no inline functions.
-
- Some comments on the many candidate routines for timing ...
-
- clock() -- We don't use because it would overflow frequently.
-
- clock_gettime() -- In tests, clock_gettime often had
- resolution = 1000.
-
- ftime() -- A "man ftime" says: "This function is obsolete.
- Don't use it." On every platform that we tested, if ftime()
- was available, then so was gettimeofday(), and gettimeofday()
- overhead was always at least as good as ftime() overhead.
-
- gettimeofday() -- available on most platforms, though not
- on Windows. There is a hardware timer (sometimes a Programmable
- Interrupt Timer or "PIT") (sometimes a "HPET") used for
- interrupt generation. When it interrupts (a "tick" or "jiffy",
- typically 1 centisecond) it sets xtime. For gettimeofday, a
- Linux kernel routine usually gets xtime and then gets rdtsc
- to get elapsed nanoseconds since the last tick. On Red Hat
- Enterprise Linux 3, there was once a bug which caused the
- resolution to be 1000, i.e. one centisecond. We never check
- for time-zone change.
-
- getnstimeofday() -- something to watch for in future Linux
-
- do_gettimeofday() -- exists on Linux but not for "userland"
-
- get_cycles() -- a multi-platform function, worth watching
- in future Linux versions. But we found platform-specific
- functions which were better documented in operating-system
- manuals. And get_cycles() can fail or return a useless
- 32-bit number. It might be available on some platforms,
- such as arm, which we didn't test. Using
- "include <linux/timex.h>" or "include <asm/timex.h>"
- can lead to autoconf or compile errors, depending on system.
-
- rdtsc, __rdtsc, rdtscll: available for x86 with Linux BSD,
- Solaris, Windows. See "possible flaws and dangers" comments.
-
- times(): what we use for ticks. Should just read the last
- (xtime) tick count, therefore should be fast, but usually
- isn't.
-
- GetTickCount(): we use this for my_timer_ticks() on
- Windows. Actually it really is a tick counter, so resolution
- >= 10 milliseconds unless you have a very old Windows version.
- With Windows 95 or 98 or ME, timeGetTime() has better resolution than
- GetTickCount (1ms rather than 55ms). But with Windows NT or XP or 2000,
- they're both getting from a variable in the Process Environment Block
- (PEB), and the variable is set by the programmable interrupt timer, so
- the resolution is the same (usually 10-15 milliseconds). Also timeGetTime
- is slower on old machines:
- http://www.doumo.jp/aon-java/jsp/postgretips/tips.jsp?tips=74.
- Also timeGetTime requires linking winmm.lib,
- Therefore we use GetTickCount.
- It will overflow every 49 days because the return is 32-bit.
- There is also a GetTickCount64 but it requires Vista or Windows Server 2008.
- (As for GetSystemTimeAsFileTime, its precision is spurious, it
- just reads the tick variable like the other functions do.
- However, we don't expect it to overflow every 49 days, so we
- will prefer it for my_timer_milliseconds().)
-
- QueryPerformanceCounter() we use this for my_timer_microseconds()
- on Windows. 1-PIT-tick (often 1/3-microsecond). Usually reads
- the PIT so it's slow. On some Windows variants, uses RDTSC.
-
- GetLocalTime() this is available on Windows but we don't use it.
-
- getclock(): documented for Alpha, but not found during tests.
-
- mach_absolute_time() and UpTime() are recommended for Apple.
- Inititally they weren't tried, because asm_ppc seems to do the job.
- But now we use mach_absolute_time for nanoseconds.
-
- Any clock-based timer can be affected by NPT (ntpd program),
- which means:
- - full-second correction can occur for leap second
- - tiny corrections can occcur approimately every 11 minutes
- (but I think they only affect the RTC which isn't the PIT).
-
- We define "precision" as "frequency" and "high precision" is
- "frequency better than 1 microsecond". We define "resolution"
- as a synonym for "granularity". We define "accuracy" as
- "closeness to the truth" as established by some authoritative
- clock, but we can't measure accuracy.
-
- Do not expect any of our timers to be monotonic; we
- won't guarantee that they return constantly-increasing
- unique numbers.
-
- We tested with AIX, Solaris (x86 + Sparc), Linux (x86 +
- Itanium), Windows, 64-bit Windows, QNX, FreeBSD, HPUX,
- Irix, Mac. We didn't test with SCO.
-
-*/
-
diff --git a/dep/mysqllite/mysys/my_read.c b/dep/mysqllite/mysys/my_read.c
deleted file mode 100644
index dbe9006a1d3..00000000000
--- a/dep/mysqllite/mysys/my_read.c
+++ /dev/null
@@ -1,97 +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"
-#include <my_base.h>
-#include <errno.h>
-
-/*
- Read a chunk of bytes from a file with retry's if needed
-
- The parameters are:
- File descriptor
- Buffer to hold at least Count bytes
- Bytes to read
- Flags on what to do on error
-
- Return:
- -1 on error
- 0 if flag has bits MY_NABP or MY_FNABP set
- N number of bytes read.
-*/
-
-size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags)
-{
- size_t readbytes, save_count;
- DBUG_ENTER("my_read");
- DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %d",
- Filedes, Buffer, (ulong) Count, MyFlags));
- save_count= Count;
-
- for (;;)
- {
- errno= 0; /* Linux, Windows don't reset this on EOF/success */
-#ifdef _WIN32
- readbytes= my_win_read(Filedes, Buffer, Count);
-#else
- readbytes= read(Filedes, Buffer, Count);
-#endif
-
- if (readbytes != Count)
- {
- my_errno= errno;
- if (errno == 0 || (readbytes != (size_t) -1 &&
- (MyFlags & (MY_NABP | MY_FNABP))))
- my_errno= HA_ERR_FILE_TOO_SHORT;
- DBUG_PRINT("warning",("Read only %d bytes off %lu from %d, errno: %d",
- (int) readbytes, (ulong) Count, Filedes,
- my_errno));
-
- if ((readbytes == 0 || (int) readbytes == -1) && errno == EINTR)
- {
- DBUG_PRINT("debug", ("my_read() was interrupted and returned %ld",
- (long) readbytes));
- continue; /* Interrupted */
- }
-
- if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
- {
- if (readbytes == (size_t) -1)
- my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
- my_filename(Filedes),my_errno);
- else if (MyFlags & (MY_NABP | MY_FNABP))
- my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
- my_filename(Filedes),my_errno);
- }
- if (readbytes == (size_t) -1 ||
- ((MyFlags & (MY_FNABP | MY_NABP)) && !(MyFlags & MY_FULL_IO)))
- DBUG_RETURN(MY_FILE_ERROR); /* Return with error */
- if (readbytes != (size_t) -1 && (MyFlags & MY_FULL_IO))
- {
- Buffer+= readbytes;
- Count-= readbytes;
- continue;
- }
- }
-
- if (MyFlags & (MY_NABP | MY_FNABP))
- readbytes= 0; /* Ok on read */
- else if (MyFlags & MY_FULL_IO)
- readbytes= save_count;
- break;
- }
- DBUG_RETURN(readbytes);
-} /* my_read */
diff --git a/dep/mysqllite/mysys/my_redel.c b/dep/mysqllite/mysys/my_redel.c
deleted file mode 100644
index 92aa6e42073..00000000000
--- a/dep/mysqllite/mysys/my_redel.c
+++ /dev/null
@@ -1,124 +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 <my_dir.h>
-#include <m_string.h>
-#include "mysys_err.h"
-#if defined(HAVE_UTIME_H)
-#include <utime.h>
-#elif defined(HAVE_SYS_UTIME_H)
-#include <sys/utime.h>
-#elif !defined(HPUX10)
-struct utimbuf {
- time_t actime;
- time_t modtime;
-};
-#endif
-
- /*
- Rename with copy stat form old file
- Copy stats from old file to new file, deletes orginal and
- changes new file name to old file name
-
- if MY_REDEL_MAKE_COPY is given, then the orginal file
- is renamed to org_name-'current_time'.BAK
- */
-
-#define REDEL_EXT ".BAK"
-
-int my_redel(const char *org_name, const char *tmp_name, myf MyFlags)
-{
- int error=1;
- DBUG_ENTER("my_redel");
- DBUG_PRINT("my",("org_name: '%s' tmp_name: '%s' MyFlags: %d",
- org_name,tmp_name,MyFlags));
-
- if (my_copystat(org_name,tmp_name,MyFlags) < 0)
- goto end;
- if (MyFlags & MY_REDEL_MAKE_BACKUP)
- {
- char name_buff[FN_REFLEN+20];
- char ext[20];
- ext[0]='-';
- get_date(ext+1,2+4,(time_t) 0);
- strmov(strend(ext),REDEL_EXT);
- if (my_rename(org_name, fn_format(name_buff, org_name, "", ext, 2),
- MyFlags))
- goto end;
- }
- else if (my_delete_allow_opened(org_name, MyFlags))
- goto end;
- if (my_rename(tmp_name,org_name,MyFlags))
- goto end;
-
- error=0;
-end:
- DBUG_RETURN(error);
-} /* my_redel */
-
-
- /* Copy stat from one file to another */
- /* Return -1 if can't get stat, 1 if wrong type of file */
-
-int my_copystat(const char *from, const char *to, int MyFlags)
-{
- struct stat statbuf;
-
- if (stat(from, &statbuf))
- {
- my_errno=errno;
- if (MyFlags & (MY_FAE+MY_WME))
- my_error(EE_STAT, MYF(ME_BELL+ME_WAITTANG),from,errno);
- return -1; /* Can't get stat on input file */
- }
- if ((statbuf.st_mode & S_IFMT) != S_IFREG)
- return 1;
-
- /* Copy modes */
- if (chmod(to, statbuf.st_mode & 07777))
- {
- my_errno= errno;
- if (MyFlags & (MY_FAE+MY_WME))
- my_error(EE_CHANGE_PERMISSIONS, MYF(ME_BELL+ME_WAITTANG), from, errno);
- return -1;
- }
-
-#if !defined(__WIN__)
- 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);
- }
- /* Copy ownership */
- if (chown(to, statbuf.st_uid, statbuf.st_gid))
- {
- my_errno= errno;
- if (MyFlags & (MY_FAE+MY_WME))
- my_error(EE_CHANGE_OWNERSHIP, MYF(ME_BELL+ME_WAITTANG), from, errno);
- return -1;
- }
-#endif /* !__WIN__ */
-
- if (MyFlags & MY_COPYTIME)
- {
- struct utimbuf timep;
- timep.actime = statbuf.st_atime;
- timep.modtime = statbuf.st_mtime;
- (void) utime((char*) to, &timep);/* Update last accessed and modified times */
- }
-
- return 0;
-} /* my_copystat */
diff --git a/dep/mysqllite/mysys/my_rename.c b/dep/mysqllite/mysys/my_rename.c
deleted file mode 100644
index 1a4e7b2b409..00000000000
--- a/dep/mysqllite/mysys/my_rename.c
+++ /dev/null
@@ -1,79 +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 <my_dir.h>
-#include "mysys_err.h"
-#include "m_string.h"
-#undef my_rename
-
- /* On unix rename deletes to file if it exists */
-
-int my_rename(const char *from, const char *to, myf MyFlags)
-{
- int error = 0;
- DBUG_ENTER("my_rename");
- DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags));
-
-#if defined(HAVE_FILE_VERSIONS)
- { /* Check that there isn't a old file */
- int save_errno;
- MY_STAT my_stat_result;
- save_errno=my_errno;
- if (my_stat(to,&my_stat_result,MYF(0)))
- {
- my_errno=EEXIST;
- error= -1;
- if (MyFlags & MY_FAE+MY_WME)
- my_error(EE_LINK, MYF(ME_BELL+ME_WAITTANG),from,to,my_errno);
- DBUG_RETURN(error);
- }
- my_errno=save_errno;
- }
-#endif
-#if defined(HAVE_RENAME)
-#if defined(__WIN__)
- /*
- On windows we can't rename over an existing file:
- Remove any conflicting files:
- */
- (void) my_delete(to, MYF(0));
-#endif
- if (rename(from,to))
-#else
- if (link(from, to) || unlink(from))
-#endif
- {
- my_errno=errno;
- error = -1;
- if (MyFlags & (MY_FAE+MY_WME))
- my_error(EE_LINK, MYF(ME_BELL+ME_WAITTANG),from,to,my_errno);
- }
- else if (MyFlags & MY_SYNC_DIR)
- {
-#ifdef NEED_EXPLICIT_SYNC_DIR
- /* do only the needed amount of syncs: */
- char dir_from[FN_REFLEN], dir_to[FN_REFLEN];
- size_t dir_from_length, dir_to_length;
- dirname_part(dir_from, from, &dir_from_length);
- dirname_part(dir_to, to, &dir_to_length);
- if (my_sync_dir(dir_from, MyFlags) ||
- (strcmp(dir_from, dir_to) &&
- my_sync_dir(dir_to, MyFlags)))
- error= -1;
-#endif
- }
- DBUG_RETURN(error);
-} /* my_rename */
diff --git a/dep/mysqllite/mysys/my_seek.c b/dep/mysqllite/mysys/my_seek.c
deleted file mode 100644
index ca12a2e95d1..00000000000
--- a/dep/mysqllite/mysys/my_seek.c
+++ /dev/null
@@ -1,102 +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"
-
-/*
- Seek to a position in a file.
-
- ARGUMENTS
- File fd The file descriptor
- my_off_t pos The expected position (absolute or relative)
- int whence A direction parameter and one of
- {SEEK_SET, SEEK_CUR, SEEK_END}
- myf MyFlags MY_THREADSAFE must be set in case my_seek may be mixed
- with my_pread/my_pwrite calls and fd is shared among
- threads.
-
- DESCRIPTION
- The my_seek function is a wrapper around the system call lseek and
- repositions the offset of the file descriptor fd to the argument
- offset according to the directive whence as follows:
- SEEK_SET The offset is set to offset bytes.
- SEEK_CUR The offset is set to its current location plus offset bytes
- SEEK_END The offset is set to the size of the file plus offset bytes
-
- RETURN VALUE
- my_off_t newpos The new position in the file.
- MY_FILEPOS_ERROR An error was encountered while performing
- the seek. my_errno is set to indicate the
- actual error.
-*/
-
-my_off_t my_seek(File fd, my_off_t pos, int whence, myf MyFlags)
-{
- os_off_t newpos= -1;
- DBUG_ENTER("my_seek");
- DBUG_PRINT("my",("fd: %d Pos: %llu Whence: %d MyFlags: %d",
- fd, (ulonglong) pos, whence, MyFlags));
- DBUG_ASSERT(pos != MY_FILEPOS_ERROR); /* safety check */
-
- /*
- Make sure we are using a valid file descriptor!
- */
- DBUG_ASSERT(fd != -1);
-#if defined (_WIN32)
- newpos= my_win_lseek(fd, pos, whence);
-#else
- newpos= lseek(fd, pos, whence);
-#endif
- if (newpos == (os_off_t) -1)
- {
- my_errno= errno;
- if (MyFlags & MY_WME)
- my_error(EE_CANT_SEEK, MYF(0), my_filename(fd), my_errno);
- DBUG_PRINT("error", ("lseek: %llu errno: %d", (ulonglong) newpos, errno));
- DBUG_RETURN(MY_FILEPOS_ERROR);
- }
- if ((my_off_t) newpos != pos)
- {
- DBUG_PRINT("exit",("pos: %llu", (ulonglong) newpos));
- }
- DBUG_RETURN((my_off_t) newpos);
-} /* my_seek */
-
-
- /* Tell current position of file */
- /* ARGSUSED */
-
-my_off_t my_tell(File fd, myf MyFlags)
-{
- os_off_t pos;
- DBUG_ENTER("my_tell");
- DBUG_PRINT("my",("fd: %d MyFlags: %d",fd, MyFlags));
- DBUG_ASSERT(fd >= 0);
-#if defined (HAVE_TELL) && !defined (_WIN32)
- pos= tell(fd);
-#else
- pos= my_seek(fd, 0L, MY_SEEK_CUR,0);
-#endif
- if (pos == (os_off_t) -1)
- {
- my_errno= errno;
- if (MyFlags & MY_WME)
- my_error(EE_CANT_SEEK, MYF(0), my_filename(fd), my_errno);
- DBUG_PRINT("error", ("tell: %llu errno: %d", (ulonglong) pos, my_errno));
- }
- DBUG_PRINT("exit",("pos: %llu", (ulonglong) pos));
- DBUG_RETURN((my_off_t) pos);
-} /* my_tell */
diff --git a/dep/mysqllite/mysys/my_sleep.c b/dep/mysqllite/mysys/my_sleep.c
deleted file mode 100644
index 6d1bdd5dc55..00000000000
--- a/dep/mysqllite/mysys/my_sleep.c
+++ /dev/null
@@ -1,35 +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 */
-
-/* Wait a given number of microseconds */
-
-#include "mysys_priv.h"
-#include <m_string.h>
-
-void my_sleep(ulong m_seconds)
-{
-#if defined(__WIN__)
- Sleep(m_seconds/1000+1); /* Sleep() has millisecond arg */
-#elif defined(HAVE_SELECT)
- struct timeval t;
- t.tv_sec= m_seconds / 1000000L;
- t.tv_usec= m_seconds % 1000000L;
- select(0,0,0,0,&t); /* sleep */
-#else
- uint sec= (uint) (m_seconds / 1000000L);
- ulong start= (ulong) time((time_t*) 0);
- while ((ulong) time((time_t*) 0) < start+sec);
-#endif
-}
diff --git a/dep/mysqllite/mysys/my_static.c b/dep/mysqllite/mysys/my_static.c
deleted file mode 100644
index ec8d66ab0cf..00000000000
--- a/dep/mysqllite/mysys/my_static.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/* Copyright (C) 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 */
-
-/*
- Static variables for mysys library. All definied here for easy making of
- a shared library
-*/
-
-#include "mysys_priv.h"
-#include "my_static.h"
-#include "my_alarm.h"
-
-my_bool timed_mutexes= 0;
-
- /* from my_init */
-char * home_dir=0;
-const char *my_progname=0;
-char curr_dir[FN_REFLEN]= {0},
- home_dir_buff[FN_REFLEN]= {0};
-ulong my_stream_opened=0,my_file_opened=0, my_tmp_file_created=0;
-ulong my_file_total_opened= 0;
-int my_umask=0664, my_umask_dir=0777;
-
-struct st_my_file_info my_file_info_default[MY_NFILE];
-uint my_file_limit= MY_NFILE;
-struct st_my_file_info *my_file_info= my_file_info_default;
-
- /* From mf_brkhant */
-int my_dont_interrupt=0;
-volatile int _my_signals=0;
-struct st_remember _my_sig_remember[MAX_SIGNALS]={{0,0}};
-
- /* from mf_reccache.c */
-ulong my_default_record_cache_size=RECORD_CACHE_SIZE;
-
- /* from soundex.c */
- /* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
- /* :::::::::::::::::::::::::: */
-const char *soundex_map= "01230120022455012623010202";
-
- /* from my_malloc */
-USED_MEM* my_once_root_block=0; /* pointer to first block */
-uint my_once_extra=ONCE_ALLOC_INIT; /* Memory to alloc / block */
-
- /* from my_largepage.c */
-#ifdef HAVE_LARGE_PAGES
-my_bool my_use_large_pages= 0;
-uint my_large_page_size= 0;
-#endif
-
- /* from my_alarm */
-int volatile my_have_got_alarm=0; /* declare variable to reset */
-ulong my_time_to_wait_for_lock=2; /* In seconds */
-
- /* from errors.c */
-#ifdef SHARED_LIBRARY
-const char *globerrs[GLOBERRS]; /* my_error_messages is here */
-#endif
-void (*my_abort_hook)(int) = (void(*)(int)) exit;
-void (*error_handler_hook)(uint error, const char *str, myf MyFlags)=
- my_message_stderr;
-void (*fatal_error_handler_hook)(uint error, const char *str, myf MyFlags)=
- my_message_stderr;
-
-static const char *proc_info_dummy(void *a __attribute__((unused)),
- const char *b __attribute__((unused)),
- const char *c __attribute__((unused)),
- const char *d __attribute__((unused)),
- const unsigned int e __attribute__((unused)))
-{
- return 0;
-}
-
-/* this is to be able to call set_thd_proc_info from the C code */
-const char *(*proc_info_hook)(void *, const char *, const char *, const char *,
- const unsigned int)= proc_info_dummy;
-
-#if defined(ENABLED_DEBUG_SYNC)
-/**
- Global pointer to be set if callback function is defined
- (e.g. in mysqld). See sql/debug_sync.cc.
-*/
-void (*debug_sync_C_callback_ptr)(const char *, size_t);
-#endif /* defined(ENABLED_DEBUG_SYNC) */
-
-#ifdef __WIN__
-/* from my_getsystime.c */
-ulonglong query_performance_frequency, query_performance_offset;
-#endif
-
- /* How to disable options */
-my_bool my_disable_locking=0;
-my_bool my_disable_async_io=0;
-my_bool my_disable_flush_key_blocks=0;
-my_bool my_disable_symlinks=0;
-
-/*
- Note that PSI_hook and PSI_server are unconditionally
- (no ifdef HAVE_PSI_INTERFACE) defined.
- This is to ensure binary compatibility between the server and plugins,
- in the case when:
- - the server is not compiled with HAVE_PSI_INTERFACE
- - a plugin is compiled with HAVE_PSI_INTERFACE
- See the doxygen documentation for the performance schema.
-*/
-
-/**
- Hook for the instrumentation interface.
- Code implementing the instrumentation interface should register here.
-*/
-struct PSI_bootstrap *PSI_hook= NULL;
-
-/**
- Instance of the instrumentation interface for the MySQL server.
- @todo This is currently a global variable, which is handy when
- compiling instrumented code that is bundled with the server.
- When dynamic plugin are truly supported, this variable will need
- to be replaced by a macro, so that each XYZ plugin can have it's own
- xyz_psi_server variable, obtained from PSI_bootstrap::get_interface()
- with the version used at compile time for plugin XYZ.
-*/
-PSI *PSI_server= NULL;
-
diff --git a/dep/mysqllite/mysys/my_static.h b/dep/mysqllite/mysys/my_static.h
deleted file mode 100644
index 7fde15ff133..00000000000
--- a/dep/mysqllite/mysys/my_static.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef MYSYS_MY_STATIC_INCLUDED
-#define MYSYS_MY_STATIC_INCLUDED
-
-/* 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 */
-
-/*
- Static variables for mysys library. All definied here for easy making of
- a shared library
-*/
-
-C_MODE_START
-#include <signal.h>
-
-#define MAX_SIGNALS 10 /* Max signals under a dont-allow */
-
-struct st_remember {
- int number;
- sig_handler (*func)(int number);
-};
-
-extern char curr_dir[FN_REFLEN], home_dir_buff[FN_REFLEN];
-
-extern volatile int _my_signals;
-extern struct st_remember _my_sig_remember[MAX_SIGNALS];
-
-extern const char *soundex_map;
-
-extern USED_MEM* my_once_root_block;
-extern uint my_once_extra;
-
-extern struct st_my_file_info my_file_info_default[MY_NFILE];
-
-extern ulonglong query_performance_frequency, query_performance_offset;
-
-C_MODE_END
-
-#endif /* MYSYS_MY_STATIC_INCLUDED */
diff --git a/dep/mysqllite/mysys/my_symlink.c b/dep/mysqllite/mysys/my_symlink.c
deleted file mode 100644
index 053fc887fe8..00000000000
--- a/dep/mysqllite/mysys/my_symlink.c
+++ /dev/null
@@ -1,167 +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"
-#include <m_string.h>
-#include <errno.h>
-#ifdef HAVE_REALPATH
-#include <sys/param.h>
-#include <sys/stat.h>
-#endif
-
-/*
- Reads the content of a symbolic link
- If the file is not a symbolic link, return the original file name in to.
-
- RETURN
- 0 If filename was a symlink, (to will be set to value of symlink)
- 1 If filename was a normal file (to will be set to filename)
- -1 on error.
-*/
-
-int my_readlink(char *to, const char *filename, myf MyFlags)
-{
-#ifndef HAVE_READLINK
- strmov(to,filename);
- return 1;
-#else
- int result=0;
- int length;
- DBUG_ENTER("my_readlink");
-
- if ((length=readlink(filename, to, FN_REFLEN-1)) < 0)
- {
- /* Don't give an error if this wasn't a symlink */
- if ((my_errno=errno) == EINVAL)
- {
- result= 1;
- strmov(to,filename);
- }
- else
- {
- if (MyFlags & MY_WME)
- my_error(EE_CANT_READLINK, MYF(0), filename, errno);
- result= -1;
- }
- }
- else
- to[length]=0;
- DBUG_PRINT("exit" ,("result: %d", result));
- DBUG_RETURN(result);
-#endif /* HAVE_READLINK */
-}
-
-
-/* Create a symbolic link */
-
-int my_symlink(const char *content, const char *linkname, myf MyFlags)
-{
-#ifndef HAVE_READLINK
- return 0;
-#else
- int result;
- DBUG_ENTER("my_symlink");
- DBUG_PRINT("enter",("content: %s linkname: %s", content, linkname));
-
- result= 0;
- if (symlink(content, linkname))
- {
- result= -1;
- my_errno=errno;
- if (MyFlags & MY_WME)
- my_error(EE_CANT_SYMLINK, MYF(0), linkname, content, errno);
- }
- else if ((MyFlags & MY_SYNC_DIR) && my_sync_dir_by_file(linkname, MyFlags))
- result= -1;
- DBUG_RETURN(result);
-#endif /* HAVE_READLINK */
-}
-
-#if defined(SCO)
-#define BUFF_LEN 4097
-#elif defined(MAXPATHLEN)
-#define BUFF_LEN MAXPATHLEN
-#else
-#define BUFF_LEN FN_LEN
-#endif
-
-
-int my_is_symlink(const char *filename __attribute__((unused)))
-{
-#if defined (HAVE_LSTAT) && defined (S_ISLNK)
- struct stat stat_buff;
- return !lstat(filename, &stat_buff) && S_ISLNK(stat_buff.st_mode);
-#elif defined (_WIN32)
- DWORD dwAttr = GetFileAttributes(filename);
- return (dwAttr != INVALID_FILE_ATTRIBUTES) &&
- (dwAttr & FILE_ATTRIBUTE_REPARSE_POINT);
-#else /* No symlinks */
- return 0;
-#endif
-}
-
-/*
- Resolve all symbolic links in path
- 'to' may be equal to 'filename'
-*/
-
-int my_realpath(char *to, const char *filename, myf MyFlags)
-{
-#if defined(HAVE_REALPATH) && !defined(HAVE_BROKEN_REALPATH)
- int result=0;
- char buff[BUFF_LEN];
- char *ptr;
- DBUG_ENTER("my_realpath");
-
- DBUG_PRINT("info",("executing realpath"));
- if ((ptr=realpath(filename,buff)))
- strmake(to,ptr,FN_REFLEN-1);
- else
- {
- /*
- Realpath didn't work; Use my_load_path() which is a poor substitute
- original name but will at least be able to resolve paths that starts
- with '.'.
- */
- DBUG_PRINT("error",("realpath failed with errno: %d", errno));
- my_errno=errno;
- if (MyFlags & MY_WME)
- my_error(EE_REALPATH, MYF(0), filename, my_errno);
- my_load_path(to, filename, NullS);
- result= -1;
- }
- DBUG_RETURN(result);
-#else
-#ifdef _WIN32
- int ret= GetFullPathName(filename,FN_REFLEN,
- to,
- NULL);
- if (ret == 0 || ret > FN_REFLEN)
- {
- if (ret > FN_REFLEN)
- my_errno= ENAMETOOLONG;
- else
- my_errno= EACCES;
- if (MyFlags & MY_WME)
- my_error(EE_REALPATH, MYF(0), filename, my_errno);
- return -1;
- }
-#else
- my_load_path(to, filename, NullS);
-#endif
- return 0;
-#endif
-}
diff --git a/dep/mysqllite/mysys/my_symlink2.c b/dep/mysqllite/mysys/my_symlink2.c
deleted file mode 100644
index 7c3ddbb911c..00000000000
--- a/dep/mysqllite/mysys/my_symlink2.c
+++ /dev/null
@@ -1,183 +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 */
-
-/*
- Advanced symlink handling.
- This is used in MyISAM to let users symlinks tables to different disk.
- The main idea with these functions is to automaticly create, delete and
- rename files and symlinks like they would be one unit.
-*/
-
-#include "mysys_priv.h"
-#include "mysys_err.h"
-#include <m_string.h>
-
-File my_create_with_symlink(const char *linkname, const char *filename,
- int createflags, int access_flags, myf MyFlags)
-{
- File file;
- int tmp_errno;
- /* Test if we should create a link */
- int create_link;
- char abs_linkname[FN_REFLEN];
- DBUG_ENTER("my_create_with_symlink");
- DBUG_PRINT("enter", ("linkname: %s filename: %s",
- linkname ? linkname : "(null)",
- filename ? filename : "(null)"));
-
- if (my_disable_symlinks)
- {
- DBUG_PRINT("info", ("Symlinks disabled"));
- /* Create only the file, not the link and file */
- create_link= 0;
- if (linkname)
- filename= linkname;
- }
- else
- {
- if (linkname)
- my_realpath(abs_linkname, linkname, MYF(0));
- create_link= (linkname && strcmp(abs_linkname,filename));
- }
-
- if (!(MyFlags & MY_DELETE_OLD))
- {
- if (!access(filename,F_OK))
- {
- my_errno= errno= EEXIST;
- my_error(EE_CANTCREATEFILE, MYF(0), filename, EEXIST);
- DBUG_RETURN(-1);
- }
- if (create_link && !access(linkname,F_OK))
- {
- my_errno= errno= EEXIST;
- my_error(EE_CANTCREATEFILE, MYF(0), linkname, EEXIST);
- DBUG_RETURN(-1);
- }
- }
-
- if ((file=my_create(filename, createflags, access_flags, MyFlags)) >= 0)
- {
- if (create_link)
- {
- /* Delete old link/file */
- if (MyFlags & MY_DELETE_OLD)
- my_delete(linkname, MYF(0));
- /* Create link */
- if (my_symlink(filename, linkname, MyFlags))
- {
- /* Fail, remove everything we have done */
- tmp_errno=my_errno;
- my_close(file,MYF(0));
- my_delete(filename, MYF(0));
- file= -1;
- my_errno=tmp_errno;
- }
- }
- }
- DBUG_RETURN(file);
-}
-
-/*
- If the file was a symlink, delete both symlink and the file which the
- symlink pointed to.
-*/
-
-int my_delete_with_symlink(const char *name, myf MyFlags)
-{
- char link_name[FN_REFLEN];
- int was_symlink= (!my_disable_symlinks &&
- !my_readlink(link_name, name, MYF(0)));
- int result;
- DBUG_ENTER("my_delete_with_symlink");
-
- if (!(result=my_delete(name, MyFlags)))
- {
- if (was_symlink)
- result=my_delete(link_name, MyFlags);
- }
- DBUG_RETURN(result);
-}
-
-/*
- If the file is a normal file, just rename it.
- If the file is a symlink:
- - Create a new file with the name 'to' that points at
- symlink_dir/basename(to)
- - Rename the symlinked file to symlink_dir/basename(to)
- - Delete 'from'
- If something goes wrong, restore everything.
-*/
-
-int my_rename_with_symlink(const char *from, const char *to, myf MyFlags)
-{
-#ifndef HAVE_READLINK
- return my_rename(from, to, MyFlags);
-#else
- char link_name[FN_REFLEN], tmp_name[FN_REFLEN];
- int was_symlink= (!my_disable_symlinks &&
- !my_readlink(link_name, from, MYF(0)));
- int result=0;
- int name_is_different;
- DBUG_ENTER("my_rename_with_symlink");
-
- if (!was_symlink)
- DBUG_RETURN(my_rename(from, to, MyFlags));
-
- /* Change filename that symlink pointed to */
- strmov(tmp_name, to);
- fn_same(tmp_name,link_name,1); /* Copy dir */
- name_is_different= strcmp(link_name, tmp_name);
- if (name_is_different && !access(tmp_name, F_OK))
- {
- my_errno= EEXIST;
- if (MyFlags & MY_WME)
- my_error(EE_CANTCREATEFILE, MYF(0), tmp_name, EEXIST);
- DBUG_RETURN(1);
- }
-
- /* Create new symlink */
- if (my_symlink(tmp_name, to, MyFlags))
- DBUG_RETURN(1);
-
- /*
- Rename symlinked file if the base name didn't change.
- This can happen if you use this function where 'from' and 'to' has
- the same basename and different directories.
- */
-
- if (name_is_different && my_rename(link_name, tmp_name, MyFlags))
- {
- int save_errno=my_errno;
- my_delete(to, MyFlags); /* Remove created symlink */
- my_errno=save_errno;
- DBUG_RETURN(1);
- }
-
- /* Remove original symlink */
- if (my_delete(from, MyFlags))
- {
- int save_errno=my_errno;
- /* Remove created link */
- my_delete(to, MyFlags);
- /* Rename file back */
- if (strcmp(link_name, tmp_name))
- (void) my_rename(tmp_name, link_name, MyFlags);
- my_errno=save_errno;
- result= 1;
- }
- DBUG_RETURN(result);
-#endif /* HAVE_READLINK */
-}
diff --git a/dep/mysqllite/mysys/my_sync.c b/dep/mysqllite/mysys/my_sync.c
deleted file mode 100644
index e33a9342afa..00000000000
--- a/dep/mysqllite/mysys/my_sync.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/* Copyright (C) 2003 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"
-#include <errno.h>
-
-/*
- Sync data in file to disk
-
- SYNOPSIS
- my_sync()
- fd File descritor to sync
- my_flags Flags (now only MY_WME is supported)
-
- NOTE
- If file system supports its, only file data is synced, not inode data.
-
- MY_IGNORE_BADFD is useful when fd is "volatile" - not protected by a
- mutex. In this case by the time of fsync(), fd may be already closed by
- another thread, or even reassigned to a different file. With this flag -
- MY_IGNORE_BADFD - such a situation will not be considered an error.
- (which is correct behaviour, if we know that the other thread synced the
- file before closing)
-
- RETURN
- 0 ok
- -1 error
-*/
-
-int my_sync(File fd, myf my_flags)
-{
- int res;
- DBUG_ENTER("my_sync");
- DBUG_PRINT("my",("Fd: %d my_flags: %d", fd, my_flags));
-
- do
- {
-#if defined(F_FULLFSYNC)
- /*
- In Mac OS X >= 10.3 this call is safer than fsync() (it forces the
- disk's cache and guarantees ordered writes).
- */
- if (!(res= fcntl(fd, F_FULLFSYNC, 0)))
- break; /* ok */
- /* Some file systems don't support F_FULLFSYNC and fail above: */
- DBUG_PRINT("info",("fcntl(F_FULLFSYNC) failed, falling back"));
-#endif
-#if defined(HAVE_FDATASYNC) && HAVE_DECL_FDATASYNC
- res= fdatasync(fd);
-#elif defined(HAVE_FSYNC)
- res= fsync(fd);
-#elif defined(_WIN32)
- res= my_win_fsync(fd);
-#else
-#error Cannot find a way to sync a file, durability in danger
- res= 0; /* No sync (strange OS) */
-#endif
- } while (res == -1 && errno == EINTR);
-
- if (res)
- {
- int er= errno;
- if (!(my_errno= er))
- my_errno= -1; /* Unknown error */
- if ((my_flags & MY_IGNORE_BADFD) &&
- (er == EBADF || er == EINVAL || er == EROFS))
- {
- DBUG_PRINT("info", ("ignoring errno %d", er));
- res= 0;
- }
- else if (my_flags & MY_WME)
- my_error(EE_SYNC, MYF(ME_BELL+ME_WAITTANG), my_filename(fd), my_errno);
- }
- DBUG_RETURN(res);
-} /* my_sync */
-
-
-static const char cur_dir_name[]= {FN_CURLIB, 0};
-
-
-/*
- Force directory information to disk.
-
- SYNOPSIS
- my_sync_dir()
- dir_name the name of the directory
- my_flags flags (MY_WME etc)
-
- RETURN
- 0 if ok, !=0 if error
-*/
-
-#ifdef NEED_EXPLICIT_SYNC_DIR
-
-int my_sync_dir(const char *dir_name, myf my_flags)
-{
- File dir_fd;
- int res= 0;
- const char *correct_dir_name;
- DBUG_ENTER("my_sync_dir");
- DBUG_PRINT("my",("Dir: '%s' my_flags: %d", dir_name, my_flags));
- /* Sometimes the path does not contain an explicit directory */
- correct_dir_name= (dir_name[0] == 0) ? cur_dir_name : dir_name;
- /*
- Syncing a dir may give EINVAL on tmpfs on Linux, which is ok.
- EIO on the other hand is very important. Hence MY_IGNORE_BADFD.
- */
- if ((dir_fd= my_open(correct_dir_name, O_RDONLY, MYF(my_flags))) >= 0)
- {
- if (my_sync(dir_fd, MYF(my_flags | MY_IGNORE_BADFD)))
- res= 2;
- if (my_close(dir_fd, MYF(my_flags)))
- res= 3;
- }
- else
- res= 1;
- DBUG_RETURN(res);
-}
-
-#else /* NEED_EXPLICIT_SYNC_DIR */
-
-int my_sync_dir(const char *dir_name __attribute__((unused)),
- myf my_flags __attribute__((unused)))
-{
- return 0;
-}
-
-#endif /* NEED_EXPLICIT_SYNC_DIR */
-
-
-/*
- Force directory information to disk.
-
- SYNOPSIS
- my_sync_dir_by_file()
- file_name the name of a file in the directory
- my_flags flags (MY_WME etc)
-
- RETURN
- 0 if ok, !=0 if error
-*/
-
-#ifdef NEED_EXPLICIT_SYNC_DIR
-
-int my_sync_dir_by_file(const char *file_name, myf my_flags)
-{
- char dir_name[FN_REFLEN];
- size_t dir_name_length;
- dirname_part(dir_name, file_name, &dir_name_length);
- return my_sync_dir(dir_name, my_flags);
-}
-
-#else /* NEED_EXPLICIT_SYNC_DIR */
-
-int my_sync_dir_by_file(const char *file_name __attribute__((unused)),
- myf my_flags __attribute__((unused)))
-{
- return 0;
-}
-
-#endif /* NEED_EXPLICIT_SYNC_DIR */
-
diff --git a/dep/mysqllite/mysys/my_thr_init.c b/dep/mysqllite/mysys/my_thr_init.c
deleted file mode 100644
index c4b56cde850..00000000000
--- a/dep/mysqllite/mysys/my_thr_init.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 */
-
-/*
- Functions to handle initializating and allocationg of all mysys & debug
- thread variables.
-*/
-
-#include "mysys_priv.h"
-#include <m_string.h>
-#include <signal.h>
-
-pthread_key(struct st_my_thread_var*, THR_KEY_mysys);
-mysql_mutex_t THR_LOCK_malloc, THR_LOCK_open,
- THR_LOCK_lock, THR_LOCK_isam, THR_LOCK_myisam, THR_LOCK_heap,
- THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads, THR_LOCK_time,
- THR_LOCK_myisam_mmap;
-
-mysql_cond_t THR_COND_threads;
-uint THR_thread_count= 0;
-uint my_thread_end_wait_time= 5;
-#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
-mysql_mutex_t LOCK_localtime_r;
-#endif
-#ifndef HAVE_GETHOSTBYNAME_R
-mysql_mutex_t LOCK_gethostbyname_r;
-#endif
-#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
-pthread_mutexattr_t my_fast_mutexattr;
-#endif
-#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
-pthread_mutexattr_t my_errorcheck_mutexattr;
-#endif
-#ifdef _MSC_VER
-static void install_sigabrt_handler();
-#endif
-#ifdef TARGET_OS_LINUX
-
-/*
- Dummy thread spawned in my_thread_global_init() below to avoid
- race conditions in NPTL pthread_exit code.
-*/
-
-static pthread_handler_t
-nptl_pthread_exit_hack_handler(void *arg __attribute((unused)))
-{
- /* Do nothing! */
- pthread_exit(0);
- return 0;
-}
-
-#endif /* TARGET_OS_LINUX */
-
-
-static uint get_thread_lib(void);
-
-/** True if @c my_thread_basic_global_init() has been called. */
-static my_bool my_thread_basic_global_init_done= 0;
-
-/**
- Perform a minimal initialisation of mysys, when compiled with threads.
- The initialisation performed is sufficient to:
- - allocate memory
- - perform file operations
- - use charsets
- - use my_errno
- @sa my_basic_init
- @sa my_thread_basic_global_reinit
-*/
-my_bool my_thread_basic_global_init(void)
-{
- int pth_ret;
-
- if (my_thread_basic_global_init_done)
- return 0;
- my_thread_basic_global_init_done= 1;
-
-#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
- /*
- Set mutex type to "fast" a.k.a "adaptive"
-
- In this case the thread may steal the mutex from some other thread
- that is waiting for the same mutex. This will save us some
- context switches but may cause a thread to 'starve forever' while
- waiting for the mutex (not likely if the code within the mutex is
- short).
- */
- pthread_mutexattr_init(&my_fast_mutexattr);
- pthread_mutexattr_settype(&my_fast_mutexattr,
- PTHREAD_MUTEX_ADAPTIVE_NP);
-#endif
-
-#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
- /*
- Set mutex type to "errorcheck"
- */
- pthread_mutexattr_init(&my_errorcheck_mutexattr);
- pthread_mutexattr_settype(&my_errorcheck_mutexattr,
- PTHREAD_MUTEX_ERRORCHECK);
-#endif
-
- mysql_mutex_init(key_THR_LOCK_malloc, &THR_LOCK_malloc, MY_MUTEX_INIT_FAST);
- mysql_mutex_init(key_THR_LOCK_open, &THR_LOCK_open, MY_MUTEX_INIT_FAST);
- mysql_mutex_init(key_THR_LOCK_charset, &THR_LOCK_charset, MY_MUTEX_INIT_FAST);
- mysql_mutex_init(key_THR_LOCK_threads, &THR_LOCK_threads, MY_MUTEX_INIT_FAST);
-
- if ((pth_ret= pthread_key_create(&THR_KEY_mysys, NULL)) != 0)
- {
- fprintf(stderr, "Can't initialize threads: error %d\n", pth_ret);
- return 1;
- }
-
- if (my_thread_init())
- return 1;
-
- return 0;
-}
-
-/**
- Re-initialize components initialized early with @c my_thread_basic_global_init.
- Some mutexes were initialized before the instrumentation.
- Destroy + create them again, now that the instrumentation
- is in place.
- This is safe, since this function() is called before creating new threads,
- so the mutexes are not in use.
-*/
-void my_thread_basic_global_reinit(void)
-{
- struct st_my_thread_var *tmp;
-
- DBUG_ASSERT(my_thread_basic_global_init_done);
-
-#ifdef HAVE_PSI_INTERFACE
- my_init_mysys_psi_keys();
-#endif
-
- mysql_mutex_destroy(&THR_LOCK_malloc);
- mysql_mutex_init(key_THR_LOCK_malloc, &THR_LOCK_malloc, MY_MUTEX_INIT_FAST);
-
- mysql_mutex_destroy(&THR_LOCK_open);
- mysql_mutex_init(key_THR_LOCK_open, &THR_LOCK_open, MY_MUTEX_INIT_FAST);
-
- mysql_mutex_destroy(&THR_LOCK_charset);
- mysql_mutex_init(key_THR_LOCK_charset, &THR_LOCK_charset, MY_MUTEX_INIT_FAST);
-
- mysql_mutex_destroy(&THR_LOCK_threads);
- mysql_mutex_init(key_THR_LOCK_threads, &THR_LOCK_threads, MY_MUTEX_INIT_FAST);
-
- tmp= my_pthread_getspecific(struct st_my_thread_var*, THR_KEY_mysys);
- DBUG_ASSERT(tmp);
-
- mysql_mutex_destroy(&tmp->mutex);
- mysql_mutex_init(key_my_thread_var_mutex, &tmp->mutex, MY_MUTEX_INIT_FAST);
-
- mysql_cond_destroy(&tmp->suspend);
- mysql_cond_init(key_my_thread_var_suspend, &tmp->suspend, NULL);
-}
-
-/*
- initialize thread environment
-
- SYNOPSIS
- my_thread_global_init()
-
- RETURN
- 0 ok
- 1 error (Couldn't create THR_KEY_mysys)
-*/
-
-my_bool my_thread_global_init(void)
-{
- if (my_thread_basic_global_init())
- return 1;
-
- thd_lib_detected= get_thread_lib();
-
-#ifdef TARGET_OS_LINUX
- /*
- BUG#24507: Race conditions inside current NPTL pthread_exit()
- implementation.
-
- To avoid a possible segmentation fault during concurrent
- executions of pthread_exit(), a dummy thread is spawned which
- initializes internal variables of pthread lib. See bug description
- for a full explanation.
-
- TODO: Remove this code when fixed versions of glibc6 are in common
- use.
- */
- if (thd_lib_detected == THD_LIB_NPTL)
- {
- pthread_t dummy_thread;
- pthread_attr_t dummy_thread_attr;
-
- pthread_attr_init(&dummy_thread_attr);
- pthread_attr_setdetachstate(&dummy_thread_attr, PTHREAD_CREATE_JOINABLE);
-
- if (pthread_create(&dummy_thread,&dummy_thread_attr,
- nptl_pthread_exit_hack_handler, NULL) == 0)
- (void)pthread_join(dummy_thread, NULL);
- }
-#endif /* TARGET_OS_LINUX */
-
- mysql_mutex_init(key_THR_LOCK_lock, &THR_LOCK_lock, MY_MUTEX_INIT_FAST);
- mysql_mutex_init(key_THR_LOCK_isam, &THR_LOCK_isam, MY_MUTEX_INIT_SLOW);
- mysql_mutex_init(key_THR_LOCK_myisam, &THR_LOCK_myisam, MY_MUTEX_INIT_SLOW);
- mysql_mutex_init(key_THR_LOCK_myisam_mmap, &THR_LOCK_myisam_mmap, MY_MUTEX_INIT_FAST);
- mysql_mutex_init(key_THR_LOCK_heap, &THR_LOCK_heap, MY_MUTEX_INIT_FAST);
- mysql_mutex_init(key_THR_LOCK_net, &THR_LOCK_net, MY_MUTEX_INIT_FAST);
- mysql_mutex_init(key_THR_LOCK_time, &THR_LOCK_time, MY_MUTEX_INIT_FAST);
- mysql_cond_init(key_THR_COND_threads, &THR_COND_threads, NULL);
-
-#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
- mysql_mutex_init(key_LOCK_localtime_r, &LOCK_localtime_r, MY_MUTEX_INIT_SLOW);
-#endif
-#ifndef HAVE_GETHOSTBYNAME_R
- mysql_mutex_init(key_LOCK_gethostbyname_r,
- &LOCK_gethostbyname_r, MY_MUTEX_INIT_SLOW);
-#endif
-
-#ifdef _MSC_VER
- install_sigabrt_handler();
-#endif
-
- if (my_thread_init())
- {
- my_thread_global_end(); /* Clean up */
- return 1;
- }
- return 0;
-}
-
-
-void my_thread_global_end(void)
-{
- struct timespec abstime;
- my_bool all_threads_killed= 1;
-
- set_timespec(abstime, my_thread_end_wait_time);
- mysql_mutex_lock(&THR_LOCK_threads);
- while (THR_thread_count > 0)
- {
- int error= mysql_cond_timedwait(&THR_COND_threads, &THR_LOCK_threads,
- &abstime);
- if (error == ETIMEDOUT || error == ETIME)
- {
-#ifdef HAVE_PTHREAD_KILL
- /*
- We shouldn't give an error here, because if we don't have
- pthread_kill(), programs like mysqld can't ensure that all threads
- are killed when we enter here.
- */
- if (THR_thread_count)
- fprintf(stderr,
- "Error in my_thread_global_end(): %d threads didn't exit\n",
- THR_thread_count);
-#endif
- all_threads_killed= 0;
- break;
- }
- }
- mysql_mutex_unlock(&THR_LOCK_threads);
-
- pthread_key_delete(THR_KEY_mysys);
-#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
- pthread_mutexattr_destroy(&my_fast_mutexattr);
-#endif
-#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
- pthread_mutexattr_destroy(&my_errorcheck_mutexattr);
-#endif
- mysql_mutex_destroy(&THR_LOCK_malloc);
- mysql_mutex_destroy(&THR_LOCK_open);
- mysql_mutex_destroy(&THR_LOCK_lock);
- mysql_mutex_destroy(&THR_LOCK_isam);
- mysql_mutex_destroy(&THR_LOCK_myisam);
- mysql_mutex_destroy(&THR_LOCK_myisam_mmap);
- mysql_mutex_destroy(&THR_LOCK_heap);
- mysql_mutex_destroy(&THR_LOCK_net);
- mysql_mutex_destroy(&THR_LOCK_time);
- mysql_mutex_destroy(&THR_LOCK_charset);
- if (all_threads_killed)
- {
- mysql_mutex_destroy(&THR_LOCK_threads);
- mysql_cond_destroy(&THR_COND_threads);
- }
-#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
- mysql_mutex_destroy(&LOCK_localtime_r);
-#endif
-#ifndef HAVE_GETHOSTBYNAME_R
- mysql_mutex_destroy(&LOCK_gethostbyname_r);
-#endif
-
- my_thread_basic_global_init_done= 0;
-}
-
-static my_thread_id thread_id= 0;
-
-/*
- Allocate thread specific memory for the thread, used by mysys and dbug
-
- SYNOPSIS
- my_thread_init()
-
- NOTES
- We can't use mutex_locks here if we are using windows as
- we may have compiled the program with SAFE_MUTEX, in which
- case the checking of mutex_locks will not work until
- the pthread_self thread specific variable is initialized.
-
- This function may called multiple times for a thread, for example
- if one uses my_init() followed by mysql_server_init().
-
- RETURN
- 0 ok
- 1 Fatal error; mysys/dbug functions can't be used
-*/
-
-my_bool my_thread_init(void)
-{
- struct st_my_thread_var *tmp;
- my_bool error=0;
-
-#ifdef EXTRA_DEBUG_THREADS
- fprintf(stderr,"my_thread_init(): thread_id: 0x%lx\n",
- (ulong) pthread_self());
-#endif
-
- if (my_pthread_getspecific(struct st_my_thread_var *,THR_KEY_mysys))
- {
-#ifdef EXTRA_DEBUG_THREADS
- fprintf(stderr,"my_thread_init() called more than once in thread 0x%lx\n",
- (long) pthread_self());
-#endif
- goto end;
- }
-
-#ifdef _MSC_VER
- install_sigabrt_handler();
-#endif
-
- if (!(tmp= (struct st_my_thread_var *) calloc(1, sizeof(*tmp))))
- {
- error= 1;
- goto end;
- }
- pthread_setspecific(THR_KEY_mysys,tmp);
- tmp->pthread_self= pthread_self();
- mysql_mutex_init(key_my_thread_var_mutex, &tmp->mutex, MY_MUTEX_INIT_FAST);
- mysql_cond_init(key_my_thread_var_suspend, &tmp->suspend, NULL);
-
- tmp->stack_ends_here= (char*)&tmp +
- STACK_DIRECTION * (long)my_thread_stack_size;
-
- mysql_mutex_lock(&THR_LOCK_threads);
- tmp->id= ++thread_id;
- ++THR_thread_count;
- mysql_mutex_unlock(&THR_LOCK_threads);
- tmp->init= 1;
-#ifndef DBUG_OFF
- /* Generate unique name for thread */
- (void) my_thread_name();
-#endif
-
-end:
- return error;
-}
-
-
-/*
- Deallocate memory used by the thread for book-keeping
-
- SYNOPSIS
- my_thread_end()
-
- NOTE
- This may be called multiple times for a thread.
- This happens for example when one calls 'mysql_server_init()'
- mysql_server_end() and then ends with a mysql_end().
-*/
-
-void my_thread_end(void)
-{
- struct st_my_thread_var *tmp;
- tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
-
-#ifdef EXTRA_DEBUG_THREADS
- fprintf(stderr,"my_thread_end(): tmp: 0x%lx pthread_self: 0x%lx thread_id: %ld\n",
- (long) tmp, (long) pthread_self(), tmp ? (long) tmp->id : 0L);
-#endif
-
-#ifdef HAVE_PSI_INTERFACE
- /*
- Remove the instrumentation for this thread.
- This must be done before trashing st_my_thread_var,
- because the LF_HASH depends on it.
- */
- if (PSI_server)
- PSI_server->delete_current_thread();
-#endif
-
- if (tmp && tmp->init)
- {
-#if !defined(DBUG_OFF)
- /* tmp->dbug is allocated inside DBUG library */
- if (tmp->dbug)
- {
- DBUG_POP();
- free(tmp->dbug);
- tmp->dbug=0;
- }
-#endif
-#if !defined(__bsdi__) && !defined(__OpenBSD__)
- /* bsdi and openbsd 3.5 dumps core here */
- mysql_cond_destroy(&tmp->suspend);
-#endif
- mysql_mutex_destroy(&tmp->mutex);
- free(tmp);
-
- /*
- Decrement counter for number of running threads. We are using this
- in my_thread_global_end() to wait until all threads have called
- my_thread_end and thus freed all memory they have allocated in
- my_thread_init() and DBUG_xxxx
- */
- mysql_mutex_lock(&THR_LOCK_threads);
- DBUG_ASSERT(THR_thread_count != 0);
- if (--THR_thread_count == 0)
- mysql_cond_signal(&THR_COND_threads);
- mysql_mutex_unlock(&THR_LOCK_threads);
- }
- pthread_setspecific(THR_KEY_mysys,0);
-}
-
-struct st_my_thread_var *_my_thread_var(void)
-{
- return my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
-}
-
-
-/****************************************************************************
- Get name of current thread.
-****************************************************************************/
-
-my_thread_id my_thread_dbug_id()
-{
- return my_thread_var->id;
-}
-
-#ifdef DBUG_OFF
-const char *my_thread_name(void)
-{
- return "no_name";
-}
-
-#else
-
-const char *my_thread_name(void)
-{
- char name_buff[100];
- struct st_my_thread_var *tmp=my_thread_var;
- if (!tmp->name[0])
- {
- my_thread_id id= my_thread_dbug_id();
- sprintf(name_buff,"T@%lu", (ulong) id);
- strmake(tmp->name,name_buff,THREAD_NAME_SIZE);
- }
- return tmp->name;
-}
-
-/* Return pointer to DBUG for holding current state */
-
-extern void **my_thread_var_dbug()
-{
- struct st_my_thread_var *tmp=
- my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
- return tmp && tmp->init ? &tmp->dbug : 0;
-}
-#endif /* DBUG_OFF */
-
-
-static uint get_thread_lib(void)
-{
-#ifdef _CS_GNU_LIBPTHREAD_VERSION
- char buff[64];
-
- confstr(_CS_GNU_LIBPTHREAD_VERSION, buff, sizeof(buff));
-
- if (!strncasecmp(buff, "NPTL", 4))
- return THD_LIB_NPTL;
- if (!strncasecmp(buff, "linuxthreads", 12))
- return THD_LIB_LT;
-#endif
- return THD_LIB_OTHER;
-}
-
-#ifdef _WIN32
-/*
- In Visual Studio 2005 and later, default SIGABRT handler will overwrite
- any unhandled exception filter set by the application and will try to
- call JIT debugger. This is not what we want, this we calling __debugbreak
- to stop in debugger, if process is being debugged or to generate
- EXCEPTION_BREAKPOINT and then handle_segfault will do its magic.
-*/
-
-#if (_MSC_VER >= 1400)
-static void my_sigabrt_handler(int sig)
-{
- __debugbreak();
-}
-#endif /*_MSC_VER >=1400 */
-
-static void install_sigabrt_handler(void)
-{
-#if (_MSC_VER >=1400)
- /*abort() should not override our exception filter*/
- _set_abort_behavior(0,_CALL_REPORTFAULT);
- signal(SIGABRT,my_sigabrt_handler);
-#endif /* _MSC_VER >=1400 */
-}
-#endif
-
diff --git a/dep/mysqllite/mysys/my_wincond.c b/dep/mysqllite/mysys/my_wincond.c
deleted file mode 100644
index 58c09e332d6..00000000000
--- a/dep/mysqllite/mysys/my_wincond.c
+++ /dev/null
@@ -1,369 +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 */
-
-/*****************************************************************************
-** The following is a simple implementation of posix conditions
-*****************************************************************************/
-#if defined(_WIN32)
-
-#undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */
-#include "mysys_priv.h"
-#include <m_string.h>
-#include <process.h>
-#include <sys/timeb.h>
-
-
-/*
- Windows native condition variables. We use runtime loading / function
- pointers, because they are not available on XP
-*/
-
-/* Prototypes and function pointers for condition variable functions */
-typedef VOID (WINAPI * InitializeConditionVariableProc)
- (PCONDITION_VARIABLE ConditionVariable);
-
-typedef BOOL (WINAPI * SleepConditionVariableCSProc)
- (PCONDITION_VARIABLE ConditionVariable,
- PCRITICAL_SECTION CriticalSection,
- DWORD dwMilliseconds);
-
-typedef VOID (WINAPI * WakeAllConditionVariableProc)
- (PCONDITION_VARIABLE ConditionVariable);
-
-typedef VOID (WINAPI * WakeConditionVariableProc)
- (PCONDITION_VARIABLE ConditionVariable);
-
-static InitializeConditionVariableProc my_InitializeConditionVariable;
-static SleepConditionVariableCSProc my_SleepConditionVariableCS;
-static WakeAllConditionVariableProc my_WakeAllConditionVariable;
-static WakeConditionVariableProc my_WakeConditionVariable;
-
-
-/**
- Indicates if we have native condition variables,
- initialized first time pthread_cond_init is called.
-*/
-
-static BOOL have_native_conditions= FALSE;
-
-
-/**
- Check if native conditions can be used, load function pointers
-*/
-
-static void check_native_cond_availability(void)
-{
- HMODULE module= GetModuleHandle("kernel32");
-
- my_InitializeConditionVariable= (InitializeConditionVariableProc)
- GetProcAddress(module, "InitializeConditionVariable");
- my_SleepConditionVariableCS= (SleepConditionVariableCSProc)
- GetProcAddress(module, "SleepConditionVariableCS");
- my_WakeAllConditionVariable= (WakeAllConditionVariableProc)
- GetProcAddress(module, "WakeAllConditionVariable");
- my_WakeConditionVariable= (WakeConditionVariableProc)
- GetProcAddress(module, "WakeConditionVariable");
-
- if (my_InitializeConditionVariable)
- have_native_conditions= TRUE;
-}
-
-
-
-/**
- Convert abstime to milliseconds
-*/
-
-static DWORD get_milliseconds(const struct timespec *abstime)
-{
- long long millis;
- union ft64 now;
-
- if (abstime == NULL)
- return INFINITE;
-
- GetSystemTimeAsFileTime(&now.ft);
-
- /*
- Calculate time left to abstime
- - subtract start time from current time(values are in 100ns units)
- - convert to millisec by dividing with 10000
- */
- millis= (abstime->tv.i64 - now.i64) / 10000;
-
- /* Don't allow the timeout to be negative */
- if (millis < 0)
- return 0;
-
- /*
- Make sure the calculated timeout does not exceed original timeout
- value which could cause "wait for ever" if system time changes
- */
- if (millis > abstime->max_timeout_msec)
- millis= abstime->max_timeout_msec;
-
- if (millis > UINT_MAX)
- millis= UINT_MAX;
-
- return (DWORD)millis;
-}
-
-
-/*
- Old (pre-vista) implementation using events
-*/
-
-static int legacy_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
-{
- cond->waiting= 0;
- InitializeCriticalSection(&cond->lock_waiting);
-
- cond->events[SIGNAL]= CreateEvent(NULL, /* no security */
- FALSE, /* auto-reset event */
- FALSE, /* non-signaled initially */
- NULL); /* unnamed */
-
- /* Create a manual-reset event. */
- cond->events[BROADCAST]= CreateEvent(NULL, /* no security */
- TRUE, /* manual-reset */
- FALSE, /* non-signaled initially */
- NULL); /* unnamed */
-
-
- cond->broadcast_block_event= CreateEvent(NULL, /* no security */
- TRUE, /* manual-reset */
- TRUE, /* signaled initially */
- NULL); /* unnamed */
-
- if( cond->events[SIGNAL] == NULL ||
- cond->events[BROADCAST] == NULL ||
- cond->broadcast_block_event == NULL )
- return ENOMEM;
- return 0;
-}
-
-
-static int legacy_cond_destroy(pthread_cond_t *cond)
-{
- DeleteCriticalSection(&cond->lock_waiting);
-
- if (CloseHandle(cond->events[SIGNAL]) == 0 ||
- CloseHandle(cond->events[BROADCAST]) == 0 ||
- CloseHandle(cond->broadcast_block_event) == 0)
- return EINVAL;
- return 0;
-}
-
-
-static int legacy_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
- struct timespec *abstime)
-{
- int result;
- DWORD timeout;
-
- timeout= get_milliseconds(abstime);
- /*
- Block access if previous broadcast hasn't finished.
- This is just for safety and should normally not
- affect the total time spent in this function.
- */
- WaitForSingleObject(cond->broadcast_block_event, INFINITE);
-
- EnterCriticalSection(&cond->lock_waiting);
- cond->waiting++;
- LeaveCriticalSection(&cond->lock_waiting);
-
- LeaveCriticalSection(mutex);
- result= WaitForMultipleObjects(2, cond->events, FALSE, timeout);
-
- EnterCriticalSection(&cond->lock_waiting);
- cond->waiting--;
-
- if (cond->waiting == 0)
- {
- /*
- We're the last waiter to be notified or to stop waiting, so
- reset the manual event.
- */
- /* Close broadcast gate */
- ResetEvent(cond->events[BROADCAST]);
- /* Open block gate */
- SetEvent(cond->broadcast_block_event);
- }
- LeaveCriticalSection(&cond->lock_waiting);
-
- EnterCriticalSection(mutex);
-
- return result == WAIT_TIMEOUT ? ETIMEDOUT : 0;
-}
-
-static int legacy_cond_signal(pthread_cond_t *cond)
-{
- EnterCriticalSection(&cond->lock_waiting);
-
- if(cond->waiting > 0)
- SetEvent(cond->events[SIGNAL]);
-
- LeaveCriticalSection(&cond->lock_waiting);
-
- return 0;
-}
-
-
-static int legacy_cond_broadcast(pthread_cond_t *cond)
-{
- EnterCriticalSection(&cond->lock_waiting);
- /*
- The mutex protect us from broadcasting if
- there isn't any thread waiting to open the
- block gate after this call has closed it.
- */
- if(cond->waiting > 0)
- {
- /* Close block gate */
- ResetEvent(cond->broadcast_block_event);
- /* Open broadcast gate */
- SetEvent(cond->events[BROADCAST]);
- }
-
- LeaveCriticalSection(&cond->lock_waiting);
-
- return 0;
-}
-
-
-/*
- Posix API functions. Just choose between native and legacy implementation.
-*/
-
-int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
-{
- /*
- Once initialization is used here rather than in my_init(), to
- 1) avoid my_init() pitfalls- undefined order in which initialization should
- run
- 2) be potentially useful C++ (in static constructors that run before main())
- 3) just to simplify the API.
- Also, the overhead of my_pthread_once is very small.
- */
- static my_pthread_once_t once_control= MY_PTHREAD_ONCE_INIT;
- my_pthread_once(&once_control, check_native_cond_availability);
-
- if (have_native_conditions)
- {
- my_InitializeConditionVariable(&cond->native_cond);
- return 0;
- }
- else
- return legacy_cond_init(cond, attr);
-}
-
-
-int pthread_cond_destroy(pthread_cond_t *cond)
-{
- if (have_native_conditions)
- return 0; /* no destroy function */
- else
- return legacy_cond_destroy(cond);
-}
-
-
-int pthread_cond_broadcast(pthread_cond_t *cond)
-{
- if (have_native_conditions)
- {
- my_WakeAllConditionVariable(&cond->native_cond);
- return 0;
- }
- else
- return legacy_cond_broadcast(cond);
-}
-
-
-int pthread_cond_signal(pthread_cond_t *cond)
-{
- if (have_native_conditions)
- {
- my_WakeConditionVariable(&cond->native_cond);
- return 0;
- }
- else
- return legacy_cond_signal(cond);
-}
-
-
-int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
- struct timespec *abstime)
-{
- if (have_native_conditions)
- {
- DWORD timeout= get_milliseconds(abstime);
- if (!my_SleepConditionVariableCS(&cond->native_cond, mutex, timeout))
- return ETIMEDOUT;
- return 0;
- }
- else
- return legacy_cond_timedwait(cond, mutex, abstime);
-}
-
-
-int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
-{
- return pthread_cond_timedwait(cond, mutex, NULL);
-}
-
-
-int pthread_attr_init(pthread_attr_t *connect_att)
-{
- connect_att->dwStackSize = 0;
- connect_att->dwCreatingFlag = 0;
- return 0;
-}
-
-int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack)
-{
- connect_att->dwStackSize=stack;
- return 0;
-}
-
-int pthread_attr_destroy(pthread_attr_t *connect_att)
-{
- bzero((uchar*) 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/dep/mysqllite/mysys/my_windac.c b/dep/mysqllite/mysys/my_windac.c
deleted file mode 100644
index 0c924188623..00000000000
--- a/dep/mysqllite/mysys/my_windac.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/* 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
- 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 "m_string.h"
-#ifdef __WIN__
-
-/* Windows NT/2000 discretionary access control utility functions. */
-
-/*
- Check if the operating system is built on NT technology.
-
- RETURN
- 0 Windows 95/98/Me
- 1 otherwise
-*/
-
-static my_bool is_nt()
-{
- return GetVersion() < 0x80000000;
-}
-
-/*
- Auxilary structure to store pointers to the data which we need to keep
- around while SECURITY_ATTRIBUTES is in use.
-*/
-
-typedef struct st_my_security_attr
-{
- PSID everyone_sid;
- PACL dacl;
-} My_security_attr;
-
-
-/*
- Allocate and initialize SECURITY_ATTRIBUTES setting up access
- rights for the owner and group `Everybody'.
-
- SYNOPSIS
- my_security_attr_create()
- psa [OUT] pointer to store the pointer to SA in
- perror [OUT] pointer to store error message if there was an
- error
- owner_rights [IN] access rights for the owner
- everyone_rights [IN] access rights for group Everybody
-
- DESCRIPTION
- Set up the security attributes to provide clients with sufficient
- access rights to a kernel object. We need this function
- because if we simply grant all access to everybody (by installing
- a NULL DACL) a mailicious user can attempt a denial of service
- attack by taking ownership over the kernel object. Upon successful
- return `psa' contains a pointer to SECUIRITY_ATTRIBUTES that can be used
- to create kernel objects with proper access rights.
-
- RETURN
- 0 success, psa is 0 or points to a valid SA structure,
- perror is left intact
- !0 error, SA is set to 0, error message is stored in perror
-*/
-
-int my_security_attr_create(SECURITY_ATTRIBUTES **psa, const char **perror,
- DWORD owner_rights, DWORD everyone_rights)
-{
- /* Top-level SID authority */
- SID_IDENTIFIER_AUTHORITY world_auth= SECURITY_WORLD_SID_AUTHORITY;
- PSID everyone_sid= 0;
- HANDLE htoken= 0;
- SECURITY_ATTRIBUTES *sa= 0;
- PACL dacl= 0;
- DWORD owner_token_length, dacl_length;
- SECURITY_DESCRIPTOR *sd;
- PTOKEN_USER owner_token;
- PSID owner_sid;
- My_security_attr *attr;
-
- if (! is_nt())
- {
- *psa= 0;
- return 0;
- }
-
- /*
- Get SID of Everyone group. Easier to retrieve all SIDs each time
- this function is called than worry about thread safety.
- */
- if (! AllocateAndInitializeSid(&world_auth, 1, SECURITY_WORLD_RID,
- 0, 0, 0, 0, 0, 0, 0, &everyone_sid))
- {
- *perror= "Failed to retrieve the SID of Everyone group";
- goto error;
- }
-
- /*
- Get SID of the owner. Using GetSecurityInfo this task can be done
- in just one call instead of five, but GetSecurityInfo declared in
- aclapi.h, so I hesitate to use it.
- SIC: OpenThreadToken works only if there is an active impersonation
- token, hence OpenProcessToken is used.
- */
- if (! OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &htoken))
- {
- *perror= "Failed to retrieve thread access token";
- goto error;
- }
- GetTokenInformation(htoken, TokenUser, 0, 0, &owner_token_length);
-
- if (! my_multi_malloc(MYF(MY_WME),
- &sa, ALIGN_SIZE(sizeof(SECURITY_ATTRIBUTES)) +
- sizeof(My_security_attr),
- &sd, sizeof(SECURITY_DESCRIPTOR),
- &owner_token, owner_token_length,
- 0))
- {
- *perror= "Failed to allocate memory for SECURITY_ATTRIBUTES";
- goto error;
- }
- bzero(owner_token, owner_token_length);
- if (! GetTokenInformation(htoken, TokenUser, owner_token,
- owner_token_length, &owner_token_length))
- {
- *perror= "GetTokenInformation failed";
- goto error;
- }
- owner_sid= owner_token->User.Sid;
-
- if (! IsValidSid(owner_sid))
- {
- *perror= "IsValidSid failed";
- goto error;
- }
-
- /* Calculate the amount of memory that must be allocated for the DACL */
- dacl_length= sizeof(ACL) + (sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD)) * 2 +
- GetLengthSid(everyone_sid) + GetLengthSid(owner_sid);
-
- /* Create an ACL */
- if (! (dacl= (PACL) my_malloc(dacl_length, MYF(MY_ZEROFILL|MY_WME))))
- {
- *perror= "Failed to allocate memory for DACL";
- goto error;
- }
- if (! InitializeAcl(dacl, dacl_length, ACL_REVISION))
- {
- *perror= "Failed to initialize DACL";
- goto error;
- }
- if (! AddAccessAllowedAce(dacl, ACL_REVISION, everyone_rights, everyone_sid))
- {
- *perror= "Failed to set up DACL";
- goto error;
- }
- if (! AddAccessAllowedAce(dacl, ACL_REVISION, owner_rights, owner_sid))
- {
- *perror= "Failed to set up DACL";
- goto error;
- }
- if (! InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION))
- {
- *perror= "Could not initialize security descriptor";
- goto error;
- }
- if (! SetSecurityDescriptorDacl(sd, TRUE, dacl, FALSE))
- {
- *perror= "Failed to install DACL";
- goto error;
- }
-
- sa->nLength= sizeof(*sa);
- sa->bInheritHandle= TRUE;
- sa->lpSecurityDescriptor= sd;
- /* Save pointers to everyone_sid and dacl to be able to clean them up */
- attr= (My_security_attr*) (((char*) sa) + ALIGN_SIZE(sizeof(*sa)));
- attr->everyone_sid= everyone_sid;
- attr->dacl= dacl;
- *psa= sa;
-
- CloseHandle(htoken);
- return 0;
-error:
- if (everyone_sid)
- FreeSid(everyone_sid);
- if (htoken)
- CloseHandle(htoken);
- my_free(sa);
- my_free(dacl);
- *psa= 0;
- return 1;
-}
-
-/*
- Cleanup security attributes freeing used memory.
-
- SYNOPSIS
- my_security_attr_free()
- sa security attributes
-*/
-
-void my_security_attr_free(SECURITY_ATTRIBUTES *sa)
-{
- if (sa)
- {
- My_security_attr *attr= (My_security_attr*)
- (((char*)sa) + ALIGN_SIZE(sizeof(*sa)));
- FreeSid(attr->everyone_sid);
- my_free(attr->dacl);
- my_free(sa);
- }
-}
-
-#endif /* __WIN__ */
diff --git a/dep/mysqllite/mysys/my_winerr.c b/dep/mysqllite/mysys/my_winerr.c
deleted file mode 100644
index 534078b6737..00000000000
--- a/dep/mysqllite/mysys/my_winerr.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/* Copyright (C) 2008 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 */
-
-/*
- Convert Windows API error (GetLastError() to Posix equivalent (errno)
- The exported function my_osmaperr() is modelled after and borrows
- heavily from undocumented _dosmaperr()(found of the static Microsoft C runtime).
-*/
-
-#include <my_global.h>
-#include <my_sys.h>
-
-
-struct errentry
-{
- unsigned long oscode; /* OS return value */
- int sysv_errno; /* System V error code */
-};
-
-static struct errentry errtable[]= {
- { ERROR_INVALID_FUNCTION, EINVAL }, /* 1 */
- { ERROR_FILE_NOT_FOUND, ENOENT }, /* 2 */
- { ERROR_PATH_NOT_FOUND, ENOENT }, /* 3 */
- { ERROR_TOO_MANY_OPEN_FILES, EMFILE }, /* 4 */
- { ERROR_ACCESS_DENIED, EACCES }, /* 5 */
- { ERROR_INVALID_HANDLE, EBADF }, /* 6 */
- { ERROR_ARENA_TRASHED, ENOMEM }, /* 7 */
- { ERROR_NOT_ENOUGH_MEMORY, ENOMEM }, /* 8 */
- { ERROR_INVALID_BLOCK, ENOMEM }, /* 9 */
- { ERROR_BAD_ENVIRONMENT, E2BIG }, /* 10 */
- { ERROR_BAD_FORMAT, ENOEXEC }, /* 11 */
- { ERROR_INVALID_ACCESS, EINVAL }, /* 12 */
- { ERROR_INVALID_DATA, EINVAL }, /* 13 */
- { ERROR_INVALID_DRIVE, ENOENT }, /* 15 */
- { ERROR_CURRENT_DIRECTORY, EACCES }, /* 16 */
- { ERROR_NOT_SAME_DEVICE, EXDEV }, /* 17 */
- { ERROR_NO_MORE_FILES, ENOENT }, /* 18 */
- { ERROR_LOCK_VIOLATION, EACCES }, /* 33 */
- { ERROR_BAD_NETPATH, ENOENT }, /* 53 */
- { ERROR_NETWORK_ACCESS_DENIED, EACCES }, /* 65 */
- { ERROR_BAD_NET_NAME, ENOENT }, /* 67 */
- { ERROR_FILE_EXISTS, EEXIST }, /* 80 */
- { ERROR_CANNOT_MAKE, EACCES }, /* 82 */
- { ERROR_FAIL_I24, EACCES }, /* 83 */
- { ERROR_INVALID_PARAMETER, EINVAL }, /* 87 */
- { ERROR_NO_PROC_SLOTS, EAGAIN }, /* 89 */
- { ERROR_DRIVE_LOCKED, EACCES }, /* 108 */
- { ERROR_BROKEN_PIPE, EPIPE }, /* 109 */
- { ERROR_DISK_FULL, ENOSPC }, /* 112 */
- { ERROR_INVALID_TARGET_HANDLE, EBADF }, /* 114 */
- { ERROR_INVALID_HANDLE, EINVAL }, /* 124 */
- { ERROR_WAIT_NO_CHILDREN, ECHILD }, /* 128 */
- { ERROR_CHILD_NOT_COMPLETE, ECHILD }, /* 129 */
- { ERROR_DIRECT_ACCESS_HANDLE, EBADF }, /* 130 */
- { ERROR_NEGATIVE_SEEK, EINVAL }, /* 131 */
- { ERROR_SEEK_ON_DEVICE, EACCES }, /* 132 */
- { ERROR_DIR_NOT_EMPTY, ENOTEMPTY }, /* 145 */
- { ERROR_NOT_LOCKED, EACCES }, /* 158 */
- { ERROR_BAD_PATHNAME, ENOENT }, /* 161 */
- { ERROR_MAX_THRDS_REACHED, EAGAIN }, /* 164 */
- { ERROR_LOCK_FAILED, EACCES }, /* 167 */
- { ERROR_ALREADY_EXISTS, EEXIST }, /* 183 */
- { ERROR_FILENAME_EXCED_RANGE, ENOENT }, /* 206 */
- { ERROR_NESTING_NOT_ALLOWED, EAGAIN }, /* 215 */
- { ERROR_NOT_ENOUGH_QUOTA, ENOMEM } /* 1816 */
-};
-
-/* size of the table */
-#define ERRTABLESIZE (sizeof(errtable)/sizeof(errtable[0]))
-
-/* The following two constants must be the minimum and maximum
-values in the (contiguous) range of Exec Failure errors. */
-#define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG
-#define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN
-
-/* These are the low and high value in the range of errors that are
-access violations */
-#define MIN_EACCES_RANGE ERROR_WRITE_PROTECT
-#define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED
-
-
-static int get_errno_from_oserr(unsigned long oserrno)
-{
- int i;
-
- /* check the table for the OS error code */
- for (i= 0; i < ERRTABLESIZE; ++i)
- {
- if (oserrno == errtable[i].oscode)
- {
- return errtable[i].sysv_errno;
- }
- }
-
- /* The error code wasn't in the table. We check for a range of */
- /* EACCES errors or exec failure errors (ENOEXEC). Otherwise */
- /* EINVAL is returned. */
-
- if (oserrno >= MIN_EACCES_RANGE && oserrno <= MAX_EACCES_RANGE)
- return EACCES;
- else if (oserrno >= MIN_EXEC_ERROR && oserrno <= MAX_EXEC_ERROR)
- return ENOEXEC;
- else
- return EINVAL;
-}
-
-/* Set errno corresponsing to GetLastError() value */
-void my_osmaperr ( unsigned long oserrno)
-{
- errno= get_errno_from_oserr(oserrno);
-}
diff --git a/dep/mysqllite/mysys/my_winfile.c b/dep/mysqllite/mysys/my_winfile.c
deleted file mode 100644
index 4d80d774dad..00000000000
--- a/dep/mysqllite/mysys/my_winfile.c
+++ /dev/null
@@ -1,681 +0,0 @@
-/* Copyright (C) 2008 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-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 */
-
-/*
- The purpose of this file is to provide implementation of file IO routines on
- Windows that can be thought as drop-in replacement for corresponding C runtime
- functionality.
-
- Compared to Windows CRT, this one
- - does not have the same file descriptor
- limitation (default is 16384 and can be increased further, whereas CRT poses
- a hard limit of 2048 file descriptors)
- - the file operations are not serialized
- - positional IO pread/pwrite is ported here.
- - no text mode for files, all IO is "binary"
-
- Naming convention:
- All routines are prefixed with my_win_, e.g Posix open() is implemented with
- my_win_open()
-
- Implemented are
- - POSIX routines(e.g open, read, lseek ...)
- - Some ANSI C stream routines (fopen, fdopen, fileno, fclose)
- - Windows CRT equvalients (my_get_osfhandle, open_osfhandle)
-
- Worth to note:
- - File descriptors used here are located in a range that is not compatible
- with CRT on purpose. Attempt to use a file descriptor from Windows CRT library
- range in my_win_* function will be punished with DBUG_ASSERT()
-
- - File streams (FILE *) are actually from the C runtime. The routines provided
- here are useful only in scernarios that use low-level IO with my_win_fileno()
-*/
-
-#ifdef _WIN32
-
-#include "mysys_priv.h"
-#include <share.h>
-#include <sys/stat.h>
-
-/* Associates a file descriptor with an existing operating-system file handle.*/
-File my_open_osfhandle(HANDLE handle, int oflag)
-{
- int offset= -1;
- uint i;
- DBUG_ENTER("my_open_osfhandle");
-
- mysql_mutex_lock(&THR_LOCK_open);
- for(i= MY_FILE_MIN; i < my_file_limit;i++)
- {
- if(my_file_info[i].fhandle == 0)
- {
- struct st_my_file_info *finfo= &(my_file_info[i]);
- finfo->type= FILE_BY_OPEN;
- finfo->fhandle= handle;
- finfo->oflag= oflag;
- offset= i;
- break;
- }
- }
- mysql_mutex_unlock(&THR_LOCK_open);
- if(offset == -1)
- errno= EMFILE; /* to many file handles open */
- DBUG_RETURN(offset);
-}
-
-
-static void invalidate_fd(File fd)
-{
- DBUG_ENTER("invalidate_fd");
- DBUG_ASSERT(fd >= MY_FILE_MIN && fd < (int)my_file_limit);
- my_file_info[fd].fhandle= 0;
- DBUG_VOID_RETURN;
-}
-
-
-/* Get Windows handle for a file descriptor */
-HANDLE my_get_osfhandle(File fd)
-{
- DBUG_ENTER("my_get_osfhandle");
- DBUG_ASSERT(fd >= MY_FILE_MIN && fd < (int)my_file_limit);
- DBUG_RETURN(my_file_info[fd].fhandle);
-}
-
-
-static int my_get_open_flags(File fd)
-{
- DBUG_ENTER("my_get_open_flags");
- DBUG_ASSERT(fd >= MY_FILE_MIN && fd < (int)my_file_limit);
- DBUG_RETURN(my_file_info[fd].oflag);
-}
-
-
-/*
- Open a file with sharing. Similar to _sopen() from libc, but allows managing
- share delete on win32
-
- SYNOPSIS
- my_win_sopen()
- path file name
- oflag operation flags
- shflag share flag
- pmode permission flags
-
- RETURN VALUE
- File descriptor of opened file if success
- -1 and sets errno if fails.
-*/
-
-File my_win_sopen(const char *path, int oflag, int shflag, int pmode)
-{
- int fh; /* handle of opened file */
- int mask;
- HANDLE osfh; /* OS handle of opened file */
- DWORD fileaccess; /* OS file access (requested) */
- DWORD fileshare; /* OS file sharing mode */
- DWORD filecreate; /* OS method of opening/creating */
- DWORD fileattrib; /* OS file attribute flags */
- SECURITY_ATTRIBUTES SecurityAttributes;
-
- DBUG_ENTER("my_win_sopen");
-
- if (check_if_legal_filename(path))
- {
- errno= EACCES;
- DBUG_RETURN(-1);
- }
- SecurityAttributes.nLength= sizeof(SecurityAttributes);
- SecurityAttributes.lpSecurityDescriptor= NULL;
- SecurityAttributes.bInheritHandle= !(oflag & _O_NOINHERIT);
-
- /* decode the access flags */
- switch (oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR)) {
- case _O_RDONLY: /* read access */
- fileaccess= GENERIC_READ;
- break;
- case _O_WRONLY: /* write access */
- fileaccess= GENERIC_WRITE;
- break;
- case _O_RDWR: /* read and write access */
- fileaccess= GENERIC_READ | GENERIC_WRITE;
- break;
- default: /* error, bad oflag */
- errno= EINVAL;
- DBUG_RETURN(-1);
- }
-
- /* decode sharing flags */
- switch (shflag) {
- case _SH_DENYRW: /* exclusive access except delete */
- fileshare= FILE_SHARE_DELETE;
- break;
- case _SH_DENYWR: /* share read and delete access */
- fileshare= FILE_SHARE_READ | FILE_SHARE_DELETE;
- break;
- case _SH_DENYRD: /* share write and delete access */
- fileshare= FILE_SHARE_WRITE | FILE_SHARE_DELETE;
- break;
- case _SH_DENYNO: /* share read, write and delete access */
- fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
- break;
- case _SH_DENYRWD: /* exclusive access */
- fileshare= 0L;
- break;
- case _SH_DENYWRD: /* share read access */
- fileshare= FILE_SHARE_READ;
- break;
- case _SH_DENYRDD: /* share write access */
- fileshare= FILE_SHARE_WRITE;
- break;
- case _SH_DENYDEL: /* share read and write access */
- fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE;
- break;
- default: /* error, bad shflag */
- errno= EINVAL;
- DBUG_RETURN(-1);
- }
-
- /* decode open/create method flags */
- switch (oflag & (_O_CREAT | _O_EXCL | _O_TRUNC)) {
- case 0:
- case _O_EXCL: /* ignore EXCL w/o CREAT */
- filecreate= OPEN_EXISTING;
- break;
-
- case _O_CREAT:
- filecreate= OPEN_ALWAYS;
- break;
-
- case _O_CREAT | _O_EXCL:
- case _O_CREAT | _O_TRUNC | _O_EXCL:
- filecreate= CREATE_NEW;
- break;
-
- case _O_TRUNC:
- case _O_TRUNC | _O_EXCL: /* ignore EXCL w/o CREAT */
- filecreate= TRUNCATE_EXISTING;
- break;
-
- case _O_CREAT | _O_TRUNC:
- filecreate= CREATE_ALWAYS;
- break;
-
- default:
- /* this can't happen ... all cases are covered */
- errno= EINVAL;
- DBUG_RETURN(-1);
- }
-
- /* decode file attribute flags if _O_CREAT was specified */
- fileattrib= FILE_ATTRIBUTE_NORMAL; /* default */
- if (oflag & _O_CREAT)
- {
- _umask((mask= _umask(0)));
-
- if (!((pmode & ~mask) & _S_IWRITE))
- fileattrib= FILE_ATTRIBUTE_READONLY;
- }
-
- /* Set temporary file (delete-on-close) attribute if requested. */
- if (oflag & _O_TEMPORARY)
- {
- fileattrib|= FILE_FLAG_DELETE_ON_CLOSE;
- fileaccess|= DELETE;
- }
-
- /* Set temporary file (delay-flush-to-disk) attribute if requested.*/
- if (oflag & _O_SHORT_LIVED)
- fileattrib|= FILE_ATTRIBUTE_TEMPORARY;
-
- /* Set sequential or random access attribute if requested. */
- if (oflag & _O_SEQUENTIAL)
- fileattrib|= FILE_FLAG_SEQUENTIAL_SCAN;
- else if (oflag & _O_RANDOM)
- fileattrib|= FILE_FLAG_RANDOM_ACCESS;
-
- /* try to open/create the file */
- if ((osfh= CreateFile(path, fileaccess, fileshare, &SecurityAttributes,
- filecreate, fileattrib, NULL)) == INVALID_HANDLE_VALUE)
- {
- /*
- OS call to open/create file failed! map the error, release
- the lock, and return -1. note that it's not necessary to
- call _free_osfhnd (it hasn't been used yet).
- */
- my_osmaperr(GetLastError()); /* map error */
- DBUG_RETURN(-1); /* return error to caller */
- }
-
- if ((fh= my_open_osfhandle(osfh,
- oflag & (_O_APPEND | _O_RDONLY | _O_TEXT))) == -1)
- {
- CloseHandle(osfh);
- }
-
- DBUG_RETURN(fh); /* return handle */
-}
-
-
-File my_win_open(const char *path, int flags)
-{
- DBUG_ENTER("my_win_open");
- DBUG_RETURN(my_win_sopen((char *) path, flags | _O_BINARY, _SH_DENYNO,
- _S_IREAD | S_IWRITE));
-}
-
-
-int my_win_close(File fd)
-{
- DBUG_ENTER("my_win_close");
- if(CloseHandle(my_get_osfhandle(fd)))
- {
- invalidate_fd(fd);
- DBUG_RETURN(0);
- }
- my_osmaperr(GetLastError());
- DBUG_RETURN(-1);
-}
-
-
-size_t my_win_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset)
-{
- DWORD nBytesRead;
- HANDLE hFile;
- OVERLAPPED ov= {0};
- LARGE_INTEGER li;
-
- DBUG_ENTER("my_win_pread");
-
- if(!Count)
- DBUG_RETURN(0);
-#ifdef _WIN64
- if(Count > UINT_MAX)
- Count= UINT_MAX;
-#endif
-
- hFile= (HANDLE)my_get_osfhandle(Filedes);
- li.QuadPart= offset;
- ov.Offset= li.LowPart;
- ov.OffsetHigh= li.HighPart;
-
- if(!ReadFile(hFile, Buffer, (DWORD)Count, &nBytesRead, &ov))
- {
- DWORD lastError= GetLastError();
- /*
- ERROR_BROKEN_PIPE is returned when no more data coming
- through e.g. a command pipe in windows : see MSDN on ReadFile.
- */
- if(lastError == ERROR_HANDLE_EOF || lastError == ERROR_BROKEN_PIPE)
- DBUG_RETURN(0); /*return 0 at EOF*/
- my_osmaperr(lastError);
- DBUG_RETURN((size_t)-1);
- }
- DBUG_RETURN(nBytesRead);
-}
-
-
-size_t my_win_read(File Filedes, uchar *Buffer, size_t Count)
-{
- DWORD nBytesRead;
- HANDLE hFile;
-
- DBUG_ENTER("my_win_read");
- if(!Count)
- DBUG_RETURN(0);
-#ifdef _WIN64
- if(Count > UINT_MAX)
- Count= UINT_MAX;
-#endif
-
- hFile= (HANDLE)my_get_osfhandle(Filedes);
-
- if(!ReadFile(hFile, Buffer, (DWORD)Count, &nBytesRead, NULL))
- {
- DWORD lastError= GetLastError();
- /*
- ERROR_BROKEN_PIPE is returned when no more data coming
- through e.g. a command pipe in windows : see MSDN on ReadFile.
- */
- if(lastError == ERROR_HANDLE_EOF || lastError == ERROR_BROKEN_PIPE)
- DBUG_RETURN(0); /*return 0 at EOF*/
- my_osmaperr(lastError);
- DBUG_RETURN((size_t)-1);
- }
- DBUG_RETURN(nBytesRead);
-}
-
-
-size_t my_win_pwrite(File Filedes, const uchar *Buffer, size_t Count,
- my_off_t offset)
-{
- DWORD nBytesWritten;
- HANDLE hFile;
- OVERLAPPED ov= {0};
- LARGE_INTEGER li;
-
- DBUG_ENTER("my_win_pwrite");
- DBUG_PRINT("my",("Filedes: %d, Buffer: %p, Count: %llu, offset: %llu",
- Filedes, Buffer, (ulonglong)Count, (ulonglong)offset));
-
- if(!Count)
- DBUG_RETURN(0);
-
-#ifdef _WIN64
- if(Count > UINT_MAX)
- Count= UINT_MAX;
-#endif
-
- hFile= (HANDLE)my_get_osfhandle(Filedes);
- li.QuadPart= offset;
- ov.Offset= li.LowPart;
- ov.OffsetHigh= li.HighPart;
-
- if(!WriteFile(hFile, Buffer, (DWORD)Count, &nBytesWritten, &ov))
- {
- my_osmaperr(GetLastError());
- DBUG_RETURN((size_t)-1);
- }
- else
- DBUG_RETURN(nBytesWritten);
-}
-
-
-my_off_t my_win_lseek(File fd, my_off_t pos, int whence)
-{
- LARGE_INTEGER offset;
- LARGE_INTEGER newpos;
-
- DBUG_ENTER("my_win_lseek");
-
- /* Check compatibility of Windows and Posix seek constants */
- compile_time_assert(FILE_BEGIN == SEEK_SET && FILE_CURRENT == SEEK_CUR
- && FILE_END == SEEK_END);
-
- offset.QuadPart= pos;
- if(!SetFilePointerEx(my_get_osfhandle(fd), offset, &newpos, whence))
- {
- my_osmaperr(GetLastError());
- newpos.QuadPart= -1;
- }
- DBUG_RETURN(newpos.QuadPart);
-}
-
-
-#ifndef FILE_WRITE_TO_END_OF_FILE
-#define FILE_WRITE_TO_END_OF_FILE 0xffffffff
-#endif
-size_t my_win_write(File fd, const uchar *Buffer, size_t Count)
-{
- DWORD nWritten;
- OVERLAPPED ov;
- OVERLAPPED *pov= NULL;
- HANDLE hFile;
-
- DBUG_ENTER("my_win_write");
- DBUG_PRINT("my",("Filedes: %d, Buffer: %p, Count %llu", fd, Buffer,
- (ulonglong)Count));
-
- if(!Count)
- DBUG_RETURN(0);
-
-#ifdef _WIN64
- if(Count > UINT_MAX)
- Count= UINT_MAX;
-#endif
-
- if(my_get_open_flags(fd) & _O_APPEND)
- {
- /*
- Atomic append to the end of file is is done by special initialization of
- the OVERLAPPED structure. See MSDN WriteFile documentation for more info.
- */
- memset(&ov, 0, sizeof(ov));
- ov.Offset= FILE_WRITE_TO_END_OF_FILE;
- ov.OffsetHigh= -1;
- pov= &ov;
- }
-
- hFile= my_get_osfhandle(fd);
- if(!WriteFile(hFile, Buffer, (DWORD)Count, &nWritten, pov))
- {
- my_osmaperr(GetLastError());
- DBUG_RETURN((size_t)-1);
- }
- DBUG_RETURN(nWritten);
-}
-
-
-int my_win_chsize(File fd, my_off_t newlength)
-{
- HANDLE hFile;
- LARGE_INTEGER length;
- DBUG_ENTER("my_win_chsize");
-
- hFile= (HANDLE) my_get_osfhandle(fd);
- length.QuadPart= newlength;
- if (!SetFilePointerEx(hFile, length , NULL , FILE_BEGIN))
- goto err;
- if (!SetEndOfFile(hFile))
- goto err;
- DBUG_RETURN(0);
-err:
- my_osmaperr(GetLastError());
- my_errno= errno;
- DBUG_RETURN(-1);
-}
-
-
-/* Get the file descriptor for stdin,stdout or stderr */
-static File my_get_stdfile_descriptor(FILE *stream)
-{
- HANDLE hFile;
- DWORD nStdHandle;
- DBUG_ENTER("my_get_stdfile_descriptor");
-
- if(stream == stdin)
- nStdHandle= STD_INPUT_HANDLE;
- else if(stream == stdout)
- nStdHandle= STD_OUTPUT_HANDLE;
- else if(stream == stderr)
- nStdHandle= STD_ERROR_HANDLE;
- else
- DBUG_RETURN(-1);
-
- hFile= GetStdHandle(nStdHandle);
- if(hFile != INVALID_HANDLE_VALUE)
- DBUG_RETURN(my_open_osfhandle(hFile, 0));
- DBUG_RETURN(-1);
-}
-
-
-File my_win_fileno(FILE *file)
-{
- HANDLE hFile= (HANDLE)_get_osfhandle(fileno(file));
- int retval= -1;
- uint i;
-
- DBUG_ENTER("my_win_fileno");
-
- for(i= MY_FILE_MIN; i < my_file_limit; i++)
- {
- if(my_file_info[i].fhandle == hFile)
- {
- retval= i;
- break;
- }
- }
- if(retval == -1)
- /* try std stream */
- DBUG_RETURN(my_get_stdfile_descriptor(file));
- DBUG_RETURN(retval);
-}
-
-
-FILE *my_win_fopen(const char *filename, const char *type)
-{
- FILE *file;
- int flags= 0;
- DBUG_ENTER("my_win_open");
-
- /*
- If we are not creating, then we need to use my_access to make sure
- the file exists since Windows doesn't handle files like "com1.sym"
- very well
- */
- if (check_if_legal_filename(filename))
- {
- errno= EACCES;
- DBUG_RETURN(NULL);
- }
-
- file= fopen(filename, type);
- if(!file)
- DBUG_RETURN(NULL);
-
- if(strchr(type,'a') != NULL)
- flags= O_APPEND;
-
- /*
- Register file handle in my_table_info.
- Necessary for my_fileno()
- */
- if(my_open_osfhandle((HANDLE)_get_osfhandle(fileno(file)), flags) < 0)
- {
- fclose(file);
- DBUG_RETURN(NULL);
- }
- DBUG_RETURN(file);
-}
-
-
-FILE * my_win_fdopen(File fd, const char *type)
-{
- FILE *file;
- int crt_fd;
- int flags= 0;
-
- DBUG_ENTER("my_win_fdopen");
-
- if(strchr(type,'a') != NULL)
- flags= O_APPEND;
- /* Convert OS file handle to CRT file descriptor and then call fdopen*/
- crt_fd= _open_osfhandle((intptr_t)my_get_osfhandle(fd), flags);
- if(crt_fd < 0)
- file= NULL;
- else
- file= fdopen(crt_fd, type);
- DBUG_RETURN(file);
-}
-
-
-int my_win_fclose(FILE *file)
-{
- File fd;
-
- DBUG_ENTER("my_win_close");
- fd= my_fileno(file);
- if(fd < 0)
- DBUG_RETURN(-1);
- if(fclose(file) < 0)
- DBUG_RETURN(-1);
- invalidate_fd(fd);
- DBUG_RETURN(0);
-}
-
-
-
-/*
- Quick and dirty my_fstat() implementation for Windows.
- Use CRT fstat on temporarily allocated file descriptor.
- Patch file size, because size that fstat returns is not
- reliable (may be outdated)
-*/
-int my_win_fstat(File fd, struct _stati64 *buf)
-{
- int crt_fd;
- int retval;
- HANDLE hFile, hDup;
-
- DBUG_ENTER("my_win_fstat");
-
- hFile= my_get_osfhandle(fd);
- if(!DuplicateHandle( GetCurrentProcess(), hFile, GetCurrentProcess(),
- &hDup ,0,FALSE,DUPLICATE_SAME_ACCESS))
- {
- my_osmaperr(GetLastError());
- DBUG_RETURN(-1);
- }
- if ((crt_fd= _open_osfhandle((intptr_t)hDup,0)) < 0)
- DBUG_RETURN(-1);
-
- retval= _fstati64(crt_fd, buf);
- if(retval == 0)
- {
- /* File size returned by stat is not accurate (may be outdated), fix it*/
- GetFileSizeEx(hDup, (PLARGE_INTEGER) (&(buf->st_size)));
- }
- _close(crt_fd);
- DBUG_RETURN(retval);
-}
-
-
-
-int my_win_stat( const char *path, struct _stati64 *buf)
-{
- DBUG_ENTER("my_win_stat");
- if(_stati64( path, buf) == 0)
- {
- /* File size returned by stat is not accurate (may be outdated), fix it*/
- WIN32_FILE_ATTRIBUTE_DATA data;
- if (GetFileAttributesEx(path, GetFileExInfoStandard, &data))
- {
- LARGE_INTEGER li;
- li.LowPart= data.nFileSizeLow;
- li.HighPart= data.nFileSizeHigh;
- buf->st_size= li.QuadPart;
- }
- DBUG_RETURN(0);
- }
- DBUG_RETURN(-1);
-}
-
-
-
-int my_win_fsync(File fd)
-{
- DBUG_ENTER("my_win_fsync");
- if(FlushFileBuffers(my_get_osfhandle(fd)))
- DBUG_RETURN(0);
- my_osmaperr(GetLastError());
- DBUG_RETURN(-1);
-}
-
-
-
-int my_win_dup(File fd)
-{
- HANDLE hDup;
- DBUG_ENTER("my_win_dup");
- if (DuplicateHandle(GetCurrentProcess(), my_get_osfhandle(fd),
- GetCurrentProcess(), &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
- {
- DBUG_RETURN(my_open_osfhandle(hDup, my_get_open_flags(fd)));
- }
- my_osmaperr(GetLastError());
- DBUG_RETURN(-1);
-}
-
-#endif /*_WIN32*/
diff --git a/dep/mysqllite/mysys/my_winthread.c b/dep/mysqllite/mysys/my_winthread.c
deleted file mode 100644
index 49534370a2f..00000000000
--- a/dep/mysqllite/mysys/my_winthread.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 */
-
-/*****************************************************************************
-** Simulation of posix threads calls for Windows
-*****************************************************************************/
-#if defined (_WIN32)
-/* SAFE_MUTEX will not work until the thread structure is up to date */
-#undef SAFE_MUTEX
-#include "mysys_priv.h"
-#include <process.h>
-#include <signal.h>
-
-static void install_sigabrt_handler(void);
-
-struct thread_start_parameter
-{
- pthread_handler func;
- void *arg;
-};
-
-/**
- Adapter to @c pthread_mutex_trylock()
-
- @retval 0 Mutex was acquired
- @retval EBUSY Mutex was already locked by a thread
- */
-int
-win_pthread_mutex_trylock(pthread_mutex_t *mutex)
-{
- if (TryEnterCriticalSection(mutex))
- {
- /* Don't allow recursive lock */
- if (mutex->RecursionCount > 1){
- LeaveCriticalSection(mutex);
- return EBUSY;
- }
- return 0;
- }
- return EBUSY;
-}
-
-static unsigned int __stdcall pthread_start(void *p)
-{
- struct thread_start_parameter *par= (struct thread_start_parameter *)p;
- pthread_handler func= par->func;
- void *arg= par->arg;
- free(p);
- (*func)(arg);
- return 0;
-}
-
-
-int pthread_create(pthread_t *thread_id, const pthread_attr_t *attr,
- pthread_handler func, void *param)
-{
- uintptr_t handle;
- struct thread_start_parameter *par;
- unsigned int stack_size;
- DBUG_ENTER("pthread_create");
-
- par= (struct thread_start_parameter *)malloc(sizeof(*par));
- if (!par)
- goto error_return;
-
- par->func= func;
- par->arg= param;
- stack_size= attr?attr->dwStackSize:0;
-
- handle= _beginthreadex(NULL, stack_size , pthread_start, par, 0, thread_id);
- if (!handle)
- goto error_return;
- DBUG_PRINT("info", ("thread id=%u",*thread_id));
-
- /* Do not need thread handle, close it */
- CloseHandle((HANDLE)handle);
- DBUG_RETURN(0);
-
-error_return:
- DBUG_PRINT("error",
- ("Can't create thread to handle request (error %d)",errno));
- DBUG_RETURN(-1);
-}
-
-
-void pthread_exit(void *a)
-{
- _endthreadex(0);
-}
-
-int pthread_join(pthread_t thread, void **value_ptr)
-{
- DWORD ret;
- HANDLE handle;
-
- handle= OpenThread(SYNCHRONIZE, FALSE, thread);
- if (!handle)
- {
- errno= EINVAL;
- goto error_return;
- }
-
- ret= WaitForSingleObject(handle, INFINITE);
-
- if(ret != WAIT_OBJECT_0)
- {
- errno= EINVAL;
- goto error_return;
- }
-
- CloseHandle(handle);
- return 0;
-
-error_return:
- if(handle)
- CloseHandle(handle);
- return -1;
-}
-
-int pthread_cancel(pthread_t thread)
-{
-
- HANDLE handle= 0;
- BOOL ok= FALSE;
-
- handle= OpenThread(THREAD_TERMINATE, FALSE, thread);
- if (handle)
- {
- ok= TerminateThread(handle,0);
- CloseHandle(handle);
- }
- if (ok)
- return 0;
-
- errno= EINVAL;
- return -1;
-}
-
-/*
- One time initialization. For simplicity, we assume initializer thread
- does not exit within init_routine().
-*/
-int my_pthread_once(my_pthread_once_t *once_control,
- void (*init_routine)(void))
-{
- LONG state;
-
- /*
- Do "dirty" read to find out if initialization is already done, to
- save an interlocked operation in common case. Memory barriers are ensured by
- Visual C++ volatile implementation.
- */
- if (*once_control == MY_PTHREAD_ONCE_DONE)
- return 0;
-
- state= InterlockedCompareExchange(once_control, MY_PTHREAD_ONCE_INPROGRESS,
- MY_PTHREAD_ONCE_INIT);
-
- switch(state)
- {
- case MY_PTHREAD_ONCE_INIT:
- /* This is initializer thread */
- (*init_routine)();
- *once_control= MY_PTHREAD_ONCE_DONE;
- break;
-
- case MY_PTHREAD_ONCE_INPROGRESS:
- /* init_routine in progress. Wait for its completion */
- while(*once_control == MY_PTHREAD_ONCE_INPROGRESS)
- {
- Sleep(1);
- }
- break;
- case MY_PTHREAD_ONCE_DONE:
- /* Nothing to do */
- break;
- }
- return 0;
-}
-#endif
diff --git a/dep/mysqllite/mysys/my_write.c b/dep/mysqllite/mysys/my_write.c
deleted file mode 100644
index 64f7546620f..00000000000
--- a/dep/mysqllite/mysys/my_write.c
+++ /dev/null
@@ -1,100 +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"
-#include <errno.h>
-
-
- /* Write a chunk of bytes to a file */
-
-size_t my_write(File Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
-{
- size_t writtenbytes, written;
- uint errors;
- DBUG_ENTER("my_write");
- DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %d",
- Filedes, Buffer, (ulong) Count, MyFlags));
- errors= 0; written= 0;
-
- /* The behavior of write(fd, buf, 0) is not portable */
- if (unlikely(!Count))
- DBUG_RETURN(0);
-
- for (;;)
- {
-#ifdef _WIN32
- writtenbytes= my_win_write(Filedes, Buffer, Count);
-#else
- writtenbytes= write(Filedes, Buffer, Count);
-#endif
- if (writtenbytes == Count)
- break;
- if (writtenbytes != (size_t) -1)
- { /* Safeguard */
- written+= writtenbytes;
- Buffer+= writtenbytes;
- Count-= writtenbytes;
- }
- my_errno= errno;
- DBUG_PRINT("error",("Write only %ld bytes, error: %d",
- (long) writtenbytes, my_errno));
-#ifndef NO_BACKGROUND
- if (my_thread_var->abort)
- MyFlags&= ~ MY_WAIT_IF_FULL; /* End if aborted by user */
-
- if ((my_errno == ENOSPC || my_errno == EDQUOT) &&
- (MyFlags & MY_WAIT_IF_FULL))
- {
- wait_for_free_space(my_filename(Filedes), errors);
- errors++;
- continue;
- }
-
- if ((writtenbytes == 0 || writtenbytes == (size_t) -1))
- {
- if (my_errno == EINTR)
- {
- DBUG_PRINT("debug", ("my_write() was interrupted and returned %ld",
- (long) writtenbytes));
- continue; /* Interrupted */
- }
-
- if (!writtenbytes && !errors++) /* Retry once */
- {
- /* We may come here if the file quota is exeeded */
- errno= EFBIG; /* Assume this is the error */
- continue;
- }
- }
- else
- continue; /* Retry */
-#endif
- if (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),my_errno);
- }
- DBUG_RETURN(MY_FILE_ERROR); /* Error on read */
- }
- else
- break; /* Return bytes written */
- }
- if (MyFlags & (MY_NABP | MY_FNABP))
- DBUG_RETURN(0); /* Want only errors */
- DBUG_RETURN(writtenbytes+written);
-} /* my_write */
diff --git a/dep/mysqllite/mysys/mysys_priv.h b/dep/mysqllite/mysys/mysys_priv.h
deleted file mode 100644
index 4e642b7e3d3..00000000000
--- a/dep/mysqllite/mysys/mysys_priv.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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_sys.h>
-
-#ifdef USE_SYSTEM_WRAPPERS
-#include "system_wrappers.h"
-#endif
-
-#ifdef HAVE_GETRUSAGE
-#include <sys/resource.h>
-#endif
-
-#include <my_pthread.h>
-
-#ifdef HAVE_PSI_INTERFACE
-
-#if !defined(HAVE_PREAD) && !defined(_WIN32)
-extern PSI_mutex_key key_my_file_info_mutex;
-#endif /* !defined(HAVE_PREAD) && !defined(_WIN32) */
-
-#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
-extern PSI_mutex_key key_LOCK_localtime_r;
-#endif /* !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) */
-
-#ifndef HAVE_GETHOSTBYNAME_R
-extern PSI_mutex_key key_LOCK_gethostbyname_r;
-#endif /* HAVE_GETHOSTBYNAME_R */
-
-extern PSI_mutex_key key_BITMAP_mutex, key_IO_CACHE_append_buffer_lock,
- key_IO_CACHE_SHARE_mutex, key_KEY_CACHE_cache_lock, key_LOCK_alarm,
- key_my_thread_var_mutex, key_THR_LOCK_charset, key_THR_LOCK_heap,
- key_THR_LOCK_isam, key_THR_LOCK_lock, key_THR_LOCK_malloc,
- key_THR_LOCK_mutex, key_THR_LOCK_myisam, key_THR_LOCK_net,
- key_THR_LOCK_open, key_THR_LOCK_threads, key_THR_LOCK_time,
- key_TMPDIR_mutex, key_THR_LOCK_myisam_mmap;
-
-extern PSI_cond_key key_COND_alarm, key_IO_CACHE_SHARE_cond,
- key_IO_CACHE_SHARE_cond_writer, key_my_thread_var_suspend,
- key_THR_COND_threads;
-
-#ifdef USE_ALARM_THREAD
-extern PSI_thread_key key_thread_alarm;
-#endif /* USE_ALARM_THREAD */
-
-#endif /* HAVE_PSI_INTERFACE */
-
-extern mysql_mutex_t THR_LOCK_malloc, THR_LOCK_open, THR_LOCK_keycache;
-extern mysql_mutex_t THR_LOCK_lock, THR_LOCK_isam, THR_LOCK_net;
-extern mysql_mutex_t THR_LOCK_charset, THR_LOCK_time;
-
-#include <mysql/psi/mysql_file.h>
-
-#ifdef HAVE_PSI_INTERFACE
-#ifdef HUGETLB_USE_PROC_MEMINFO
-extern PSI_file_key key_file_proc_meminfo;
-#endif /* HUGETLB_USE_PROC_MEMINFO */
-extern PSI_file_key key_file_charset, key_file_cnf;
-#endif /* HAVE_PSI_INTERFACE */
-
-/*
- EDQUOT is used only in 3 C files only in mysys/. If it does not exist on
- system, we set it to some value which can never happen.
-*/
-#ifndef EDQUOT
-#define EDQUOT (-1)
-#endif
-
-void my_error_unregister_all(void);
-
-#ifdef _WIN32
-#include <sys/stat.h>
-/* my_winfile.c exports, should not be used outside mysys */
-extern File my_win_open(const char *path, int oflag);
-extern int my_win_close(File fd);
-extern size_t my_win_read(File fd, uchar *buffer, size_t count);
-extern size_t my_win_write(File fd, const uchar *buffer, size_t count);
-extern size_t my_win_pread(File fd, uchar *buffer, size_t count,
- my_off_t offset);
-extern size_t my_win_pwrite(File fd, const uchar *buffer, size_t count,
- my_off_t offset);
-extern my_off_t my_win_lseek(File fd, my_off_t pos, int whence);
-extern int my_win_chsize(File fd, my_off_t newlength);
-extern FILE* my_win_fopen(const char *filename, const char *type);
-extern File my_win_fclose(FILE *file);
-extern File my_win_fileno(FILE *file);
-extern FILE* my_win_fdopen(File Filedes, const char *type);
-extern int my_win_stat(const char *path, struct _stati64 *buf);
-extern int my_win_fstat(File fd, struct _stati64 *buf);
-extern int my_win_fsync(File fd);
-extern File my_win_dup(File fd);
-extern File my_win_sopen(const char *path, int oflag, int shflag, int perm);
-extern File my_open_osfhandle(HANDLE handle, int oflag);
-#endif
diff --git a/dep/mysqllite/mysys/ptr_cmp.c b/dep/mysqllite/mysys/ptr_cmp.c
deleted file mode 100644
index dcafe13291d..00000000000
--- a/dep/mysqllite/mysys/ptr_cmp.c
+++ /dev/null
@@ -1,223 +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 */
-
-/*
- get_ptr_compare(len) returns a pointer to a optimal byte-compare function
- for a array of stringpointer where all strings have size len.
- The bytes are compare as unsigned chars.
- */
-
-#include "mysys_priv.h"
-#include <myisampack.h>
-
-#ifdef __sun
-/*
- * On Solaris, memcmp() is normally faster than the unrolled ptr_compare_N
- * functions, as memcmp() is usually a platform-specific implementation
- * written in assembler, provided in /usr/lib/libc/libc_hwcap*.so.1.
- * This implementation is also usually faster than the built-in memcmp
- * supplied by GCC, so it is recommended to build with "-fno-builtin-memcmp"
- * in CFLAGS if building with GCC on Solaris.
- */
-
-#include <string.h>
-
-static int native_compare(size_t *length, unsigned char **a, unsigned char **b)
-{
- return memcmp(*a, *b, *length);
-}
-
-#else /* __sun */
-
-static int ptr_compare(size_t *compare_length, uchar **a, uchar **b);
-static int ptr_compare_0(size_t *compare_length, uchar **a, uchar **b);
-static int ptr_compare_1(size_t *compare_length, uchar **a, uchar **b);
-static int ptr_compare_2(size_t *compare_length, uchar **a, uchar **b);
-static int ptr_compare_3(size_t *compare_length, uchar **a, uchar **b);
-#endif /* __sun */
-
- /* Get a pointer to a optimal byte-compare function for a given size */
-
-#ifdef __sun
-qsort2_cmp get_ptr_compare (size_t size __attribute__((unused)))
-{
- return (qsort2_cmp) native_compare;
-}
-#else
-qsort2_cmp get_ptr_compare (size_t size)
-{
- if (size < 4)
- return (qsort2_cmp) ptr_compare;
- switch (size & 3) {
- case 0: return (qsort2_cmp) ptr_compare_0;
- case 1: return (qsort2_cmp) ptr_compare_1;
- case 2: return (qsort2_cmp) ptr_compare_2;
- case 3: return (qsort2_cmp) ptr_compare_3;
- }
- return 0; /* Impossible */
-}
-#endif /* __sun */
-
-
- /*
- Compare to keys to see witch is smaller.
- Loop unrolled to make it quick !!
- */
-
-#define cmp(N) if (first[N] != last[N]) return (int) first[N] - (int) last[N]
-
-#ifndef __sun
-
-static int ptr_compare(size_t *compare_length, uchar **a, uchar **b)
-{
- reg3 int length= *compare_length;
- reg1 uchar *first,*last;
-
- first= *a; last= *b;
- while (--length)
- {
- if (*first++ != *last++)
- return (int) first[-1] - (int) last[-1];
- }
- return (int) first[0] - (int) last[0];
-}
-
-
-static int ptr_compare_0(size_t *compare_length,uchar **a, uchar **b)
-{
- reg3 int length= *compare_length;
- reg1 uchar *first,*last;
-
- first= *a; last= *b;
- loop:
- cmp(0);
- cmp(1);
- cmp(2);
- cmp(3);
- if ((length-=4))
- {
- first+=4;
- last+=4;
- goto loop;
- }
- return (0);
-}
-
-
-static int ptr_compare_1(size_t *compare_length,uchar **a, uchar **b)
-{
- reg3 int length= *compare_length-1;
- reg1 uchar *first,*last;
-
- first= *a+1; last= *b+1;
- cmp(-1);
- loop:
- cmp(0);
- cmp(1);
- cmp(2);
- cmp(3);
- if ((length-=4))
- {
- first+=4;
- last+=4;
- goto loop;
- }
- return (0);
-}
-
-static int ptr_compare_2(size_t *compare_length,uchar **a, uchar **b)
-{
- reg3 int length= *compare_length-2;
- reg1 uchar *first,*last;
-
- first= *a +2 ; last= *b +2;
- cmp(-2);
- cmp(-1);
- loop:
- cmp(0);
- cmp(1);
- cmp(2);
- cmp(3);
- if ((length-=4))
- {
- first+=4;
- last+=4;
- goto loop;
- }
- return (0);
-}
-
-static int ptr_compare_3(size_t *compare_length,uchar **a, uchar **b)
-{
- reg3 int length= *compare_length-3;
- reg1 uchar *first,*last;
-
- first= *a +3 ; last= *b +3;
- cmp(-3);
- cmp(-2);
- cmp(-1);
- loop:
- cmp(0);
- cmp(1);
- cmp(2);
- cmp(3);
- if ((length-=4))
- {
- first+=4;
- last+=4;
- goto loop;
- }
- return (0);
-}
-
-#endif /* !__sun */
-
-void my_store_ptr(uchar *buff, size_t pack_length, my_off_t pos)
-{
- switch (pack_length) {
-#if SIZEOF_OFF_T > 4
- case 8: mi_int8store(buff,pos); break;
- case 7: mi_int7store(buff,pos); break;
- case 6: mi_int6store(buff,pos); break;
- case 5: mi_int5store(buff,pos); break;
-#endif
- case 4: mi_int4store(buff,pos); break;
- case 3: mi_int3store(buff,pos); break;
- case 2: mi_int2store(buff,pos); break;
- case 1: buff[0]= (uchar) pos; break;
- default: DBUG_ASSERT(0);
- }
- return;
-}
-
-my_off_t my_get_ptr(uchar *ptr, size_t pack_length)
-{
- my_off_t pos;
- switch (pack_length) {
-#if SIZEOF_OFF_T > 4
- case 8: pos= (my_off_t) mi_uint8korr(ptr); break;
- case 7: pos= (my_off_t) mi_uint7korr(ptr); break;
- case 6: pos= (my_off_t) mi_uint6korr(ptr); break;
- case 5: pos= (my_off_t) mi_uint5korr(ptr); break;
-#endif
- 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) *(uchar*) ptr; break;
- default: DBUG_ASSERT(0); return 0;
- }
- return pos;
-}
-
diff --git a/dep/mysqllite/mysys/queues.c b/dep/mysqllite/mysys/queues.c
deleted file mode 100644
index 25a310c0752..00000000000
--- a/dep/mysqllite/mysys/queues.c
+++ /dev/null
@@ -1,687 +0,0 @@
-/* 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
- 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 */
-
-/*
- 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"
-#include "mysys_err.h"
-#include <queues.h>
-
-
-/*
- Init queue
-
- SYNOPSIS
- init_queue()
- 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
-
- NOTES
- Will allocate max_element pointers for queue array
-
- RETURN
- 0 ok
- 1 Could not allocate memory
-*/
-
-int init_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
- pbool max_at_top, int (*compare) (void *, uchar *, uchar *),
- void *first_cmp_arg)
-{
- DBUG_ENTER("init_queue");
- if ((queue->root= (uchar **) my_malloc((max_elements+1)*sizeof(void*),
- MYF(MY_WME))) == 0)
- DBUG_RETURN(1);
- queue->elements=0;
- queue->compare=compare;
- queue->first_cmp_arg=first_cmp_arg;
- queue->max_elements=max_elements;
- queue->offset_to_key=offset_to_key;
- queue_set_max_at_top(queue, max_at_top);
- DBUG_RETURN(0);
-}
-
-
-
-/*
- 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 *, uchar *, uchar *),
- 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
-
- SYNOPSIS
- reinit_queue()
- 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
-
- NOTES
- This will delete all elements from the queue. If you don't want this,
- use resize_queue() instead.
-
- RETURN
- 0 ok
- EE_OUTOFMEMORY Wrong max_elements
-*/
-
-int reinit_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
- pbool max_at_top, int (*compare) (void *, uchar *, uchar *),
- void *first_cmp_arg)
-{
- DBUG_ENTER("reinit_queue");
- queue->elements=0;
- queue->compare=compare;
- queue->first_cmp_arg=first_cmp_arg;
- queue->offset_to_key=offset_to_key;
- queue_set_max_at_top(queue, max_at_top);
- resize_queue(queue, max_elements);
- DBUG_RETURN(0);
-}
-
-
-/*
- Resize queue
-
- SYNOPSIS
- resize_queue()
- queue Queue
- max_elements New max size for queue
-
- NOTES
- If you resize queue to be less than the elements you have in it,
- the extra elements will be deleted
-
- RETURN
- 0 ok
- 1 Error. In this case the queue is unchanged
-*/
-
-int resize_queue(QUEUE *queue, uint max_elements)
-{
- uchar **new_root;
- DBUG_ENTER("resize_queue");
- if (queue->max_elements == max_elements)
- DBUG_RETURN(0);
- if ((new_root= (uchar **) my_realloc((void *)queue->root,
- (max_elements+1)*sizeof(void*),
- MYF(MY_WME))) == 0)
- DBUG_RETURN(1);
- set_if_smaller(queue->elements, max_elements);
- queue->max_elements= max_elements;
- queue->root= new_root;
- DBUG_RETURN(0);
-}
-
-
-/*
- Delete queue
-
- SYNOPSIS
- delete_queue()
- queue Queue to delete
-
- IMPLEMENTATION
- Just free allocated memory.
-
- NOTES
- Can be called safely multiple times
-*/
-
-void delete_queue(QUEUE *queue)
-{
- DBUG_ENTER("delete_queue");
- my_free(queue->root);
- queue->root= NULL;
- DBUG_VOID_RETURN;
-}
-
-
- /* Code for insert, search and delete of elements */
-
-void queue_insert(register QUEUE *queue, uchar *element)
-{
- reg2 uint idx, next;
- DBUG_ASSERT(queue->elements < queue->max_elements);
- queue->root[0]= element;
- idx= ++queue->elements;
- /* max_at_top swaps the comparison if we want to order by desc */
- while ((queue->compare(queue->first_cmp_arg,
- element + queue->offset_to_key,
- queue->root[(next= idx >> 1)] +
- queue->offset_to_key) * queue->max_at_top) < 0)
- {
- queue->root[idx]= queue->root[next];
- idx= next;
- }
- 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, uchar *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 */
-
-uchar *queue_remove(register QUEUE *queue, uint idx)
-{
- uchar *element;
- DBUG_ASSERT(idx < queue->max_elements);
- element= queue->root[++idx]; /* Intern index starts from 1 */
- queue->root[idx]= queue->root[queue->elements--];
- _downheap(queue, idx);
- return element;
-}
-
- /* Fix when element on top has been replaced */
-
-#ifndef queue_replaced
-void queue_replaced(QUEUE *queue)
-{
- _downheap(queue,1);
-}
-#endif
-
-#ifndef OLD_VERSION
-
-void _downheap(register QUEUE *queue, uint idx)
-{
- uchar *element;
- uint elements,half_queue,offset_to_key, next_index;
- my_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)
- {
- 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 &&
- (((queue->compare(queue->first_cmp_arg,
- queue->root[next_index]+offset_to_key,
- element+offset_to_key) * 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)
-{
- uchar *element;
- uint elements,half_queue,next_index,offset_to_key;
-
- offset_to_key=queue->offset_to_key;
- element=queue->root[idx];
- half_queue=(elements=queue->elements) >> 1;
-
- while (idx <= half_queue)
- {
- 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 ((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;
- }
- queue->root[idx]=element;
-}
-
-
-#endif
-
-/*
- Fix heap when every element was changed.
-*/
-
-void queue_fix(QUEUE *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, uchar *a, uchar *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)= (uchar*)&num_array[i];
- else
- queue_insert(queue, (uchar*)&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)= (uchar*)&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)= (uchar*)&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/dep/mysqllite/mysys/rijndael.c b/dep/mysqllite/mysys/rijndael.c
deleted file mode 100644
index 2d622efad82..00000000000
--- a/dep/mysqllite/mysys/rijndael.c
+++ /dev/null
@@ -1,1379 +0,0 @@
-/* Copyright (C) 2002, 2004 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 */
-
-
-/*
- Based on version 3.0 (December 2000)
-
- Optimised ANSI C code for the Rijndael cipher (now AES)
-
- author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
- author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
- author Paulo Barreto <paulo.barreto@terra.com.br>
-*/
-
-#include <my_global.h>
-#include "rijndael.h"
-
-/*
- Define the following to use fastest and much larger code (~10K extra code)
- #define FULL_UNROLL
-*/
-
-static const uint32 Te0[256]=
-{
- 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
- 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
- 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
- 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
- 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
- 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
- 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
- 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
- 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
- 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
- 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
- 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
- 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
- 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
- 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
- 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
- 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
- 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
- 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
- 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
- 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
- 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
- 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
- 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
- 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
- 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
- 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
- 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
- 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
- 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
- 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
- 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
- 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
- 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
- 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
- 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
- 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
- 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
- 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
- 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
- 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
- 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
- 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
- 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
- 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
- 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
- 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
- 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
- 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
- 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
- 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
- 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
- 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
- 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
- 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
- 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
- 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
- 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
- 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
- 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
- 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
- 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
- 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
- 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
-};
-
-static const uint32 Te1[256]=
-{
- 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
- 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
- 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
- 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
- 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
- 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
- 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
- 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
- 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
- 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
- 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
- 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
- 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
- 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
- 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
- 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
- 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
- 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
- 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
- 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
- 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
- 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
- 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
- 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
- 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
- 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
- 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
- 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
- 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
- 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
- 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
- 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
- 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
- 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
- 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
- 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
- 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
- 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
- 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
- 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
- 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
- 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
- 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
- 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
- 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
- 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
- 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
- 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
- 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
- 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
- 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
- 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
- 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
- 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
- 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
- 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
- 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
- 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
- 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
- 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
- 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
- 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
- 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
- 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
-};
-
-static const uint32 Te2[256]=
-{
- 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
- 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
- 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
- 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
- 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
- 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
- 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
- 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
- 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
- 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
- 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
- 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
- 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
- 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
- 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
- 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
- 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
- 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
- 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
- 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
- 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
- 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
- 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
- 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
- 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
- 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
- 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
- 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
- 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
- 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
- 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
- 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
- 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
- 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
- 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
- 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
- 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
- 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
- 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
- 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
- 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
- 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
- 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
- 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
- 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
- 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
- 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
- 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
- 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
- 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
- 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
- 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
- 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
- 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
- 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
- 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
- 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
- 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
- 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
- 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
- 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
- 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
- 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
- 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
-};
-
-static const uint32 Te3[256]=
-{
- 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
- 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
- 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
- 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
- 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
- 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
- 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
- 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
- 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
- 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
- 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
- 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
- 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
- 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
- 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
- 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
- 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
- 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
- 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
- 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
- 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
- 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
- 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
- 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
- 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
- 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
- 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
- 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
- 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
- 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
- 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
- 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
- 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
- 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
- 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
- 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
- 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
- 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
- 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
- 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
- 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
- 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
- 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
- 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
- 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
- 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
- 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
- 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
- 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
- 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
- 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
- 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
- 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
- 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
- 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
- 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
- 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
- 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
- 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
- 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
- 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
- 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
- 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
- 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
-};
-
-static const uint32 Te4[256]=
-{
- 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
- 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
- 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
- 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
- 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
- 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
- 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
- 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
- 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
- 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
- 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
- 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
- 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
- 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
- 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
- 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
- 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
- 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
- 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
- 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
- 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
- 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
- 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
- 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
- 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
- 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
- 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
- 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
- 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
- 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
- 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
- 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
- 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
- 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
- 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
- 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
- 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
- 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
- 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
- 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
- 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
- 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
- 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
- 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
- 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
- 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
- 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
- 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
- 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
- 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
- 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
- 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
- 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
- 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
- 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
- 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
- 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
- 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
- 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
- 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
- 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
- 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
- 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
- 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
-};
-
-static const uint32 Td0[256]=
-{
- 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
- 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
- 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
- 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
- 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
- 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
- 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
- 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
- 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
- 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
- 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
- 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
- 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
- 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
- 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
- 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
- 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
- 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
- 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
- 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
- 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
- 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
- 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
- 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
- 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
- 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
- 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
- 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
- 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
- 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
- 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
- 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
- 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
- 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
- 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
- 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
- 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
- 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
- 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
- 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
- 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
- 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
- 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
- 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
- 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
- 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
- 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
- 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
- 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
- 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
- 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
- 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
- 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
- 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
- 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
- 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
- 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
- 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
- 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
- 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
- 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
- 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
- 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
- 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
-};
-
-static const uint32 Td1[256]=
-{
- 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
- 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
- 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
- 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
- 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
- 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
- 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
- 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
- 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
- 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
- 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
- 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
- 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
- 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
- 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
- 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
- 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
- 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
- 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
- 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
- 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
- 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
- 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
- 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
- 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
- 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
- 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
- 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
- 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
- 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
- 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
- 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
- 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
- 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
- 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
- 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
- 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
- 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
- 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
- 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
- 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
- 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
- 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
- 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
- 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
- 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
- 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
- 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
- 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
- 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
- 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
- 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
- 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
- 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
- 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
- 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
- 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
- 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
- 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
- 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
- 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
- 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
- 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
- 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
-};
-
-static const uint32 Td2[256]=
-{
- 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
- 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
- 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
- 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
- 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
- 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
- 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
- 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
- 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
- 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
- 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
- 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
- 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
- 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
- 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
- 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
- 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
- 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
- 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
- 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
-
- 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
- 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
- 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
- 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
- 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
- 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
- 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
- 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
- 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
- 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
- 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
- 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
- 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
- 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
- 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
- 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
- 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
- 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
- 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
- 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
- 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
- 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
- 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
- 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
- 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
- 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
- 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
- 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
- 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
- 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
- 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
- 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
- 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
- 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
- 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
- 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
- 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
- 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
- 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
- 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
- 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
- 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
- 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
- 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
-};
-
-static const uint32 Td3[256]=
-{
- 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
- 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
- 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
- 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
- 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
- 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
- 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
- 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
- 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
- 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
- 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
- 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
- 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
- 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
- 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
- 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
- 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
- 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
- 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
- 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
- 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
- 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
- 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
- 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
- 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
- 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
- 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
- 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
- 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
- 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
- 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
- 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
- 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
- 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
- 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
- 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
- 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
- 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
- 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
- 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
- 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
- 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
- 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
- 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
- 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
- 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
- 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
- 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
- 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
- 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
- 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
- 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
- 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
- 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
- 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
- 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
- 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
- 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
- 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
- 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
- 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
- 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
- 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
- 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
-};
-
-static const uint32 Td4[256]=
-{
- 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
- 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
- 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
- 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
- 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
- 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
- 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
- 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
- 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
- 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
- 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
- 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
- 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
- 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
- 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
- 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
- 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
- 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
- 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
- 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
- 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
- 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
- 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
- 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
- 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
- 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
- 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
- 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
- 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
- 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
- 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
- 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
- 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
- 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
- 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
- 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
- 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
- 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
- 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
- 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
- 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
- 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
- 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
- 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
- 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
- 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
- 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
- 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
- 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
- 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
- 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
- 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
- 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
- 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
- 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
- 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
- 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
- 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
- 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
- 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
- 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
- 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
- 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
- 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
-};
-
-
-/* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
-static const uint32 rcon[]=
-{
- 0x01000000, 0x02000000, 0x04000000, 0x08000000,
- 0x10000000, 0x20000000, 0x40000000, 0x80000000,
- 0x1B000000, 0x36000000,
-};
-
-#if defined(_MSC_VER) && defined(__i386__)
-
-#define RJ_SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
-#define GETuint32(p) RJ_SWAP(*((uint32 *)(p)))
-#define PUTuint32(ct, st) { *((uint32 *)(ct)) = RJ_SWAP((st)); }
-
-#else
-
-#define GETuint32(pt) (((uint32)(pt)[0] << 24) ^ ((uint32)(pt)[1] << 16)\
- ^ ((uint32)(pt)[2] << 8) ^ ((uint32)(pt)[3]))
-#define PUTuint32(ct, st) { (ct)[0] = (uint8)((st) >> 24); (ct)[1]\
-= (uint8)((st) >> 16); (ct)[2] = (uint8)((st) >> 8); (ct)[3] = (uint8)(st); }
-
-#endif /* defined(_MSC_VER) && defined(__i386__) */
-
-
-/*
- Expand the cipher key into the encryption key schedule.
-
- RETURN
- The number of rounds for the given cipher key size.
-*/
-
-int rijndaelKeySetupEnc(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[],
- int keyBits)
-{
- int i = 0;
- uint32 temp;
-
- rk[0] = GETuint32(cipherKey );
- rk[1] = GETuint32(cipherKey + 4);
- rk[2] = GETuint32(cipherKey + 8);
- rk[3] = GETuint32(cipherKey + 12);
- if (keyBits == 128)
- {
- for (;;)
- {
- temp = rk[3];
- rk[4] = (rk[0] ^
- (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
- (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
- (Te4[(temp ) & 0xff] & 0x0000ff00) ^
- (Te4[(temp >> 24) ] & 0x000000ff) ^
- rcon[i]);
- rk[5] = rk[1] ^ rk[4];
- rk[6] = rk[2] ^ rk[5];
- rk[7] = rk[3] ^ rk[6];
- if (++i == 10)
- return 10;
- rk += 4;
- }
- }
- rk[4] = GETuint32(cipherKey + 16);
- rk[5] = GETuint32(cipherKey + 20);
- if (keyBits == 192)
- {
- for (;;)
- {
- temp = rk[ 5];
- rk[ 6] = (rk[ 0] ^
- (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
- (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
- (Te4[(temp ) & 0xff] & 0x0000ff00) ^
- (Te4[(temp >> 24) ] & 0x000000ff) ^
- rcon[i]);
- rk[ 7] = rk[ 1] ^ rk[ 6];
- rk[ 8] = rk[ 2] ^ rk[ 7];
- rk[ 9] = rk[ 3] ^ rk[ 8];
- if (++i == 8)
- {
- return 12;
- }
- rk[10] = rk[ 4] ^ rk[ 9];
- rk[11] = rk[ 5] ^ rk[10];
- rk += 6;
- }
- }
- rk[6] = GETuint32(cipherKey + 24);
- rk[7] = GETuint32(cipherKey + 28);
- if (keyBits == 256)
- {
- for (;;)
- {
- temp = rk[ 7];
- rk[ 8] = (rk[ 0] ^
- (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
- (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
- (Te4[(temp ) & 0xff] & 0x0000ff00) ^
- (Te4[(temp >> 24) ] & 0x000000ff) ^
- rcon[i]);
- rk[ 9] = rk[ 1] ^ rk[ 8];
- rk[10] = rk[ 2] ^ rk[ 9];
- rk[11] = rk[ 3] ^ rk[10];
- if (++i == 7)
- {
- return 14;
- }
- temp = rk[11];
- rk[12] = (rk[ 4] ^
- (Te4[(temp >> 24) ] & 0xff000000) ^
- (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(temp ) & 0xff] & 0x000000ff));
- rk[13] = rk[ 5] ^ rk[12];
- rk[14] = rk[ 6] ^ rk[13];
- rk[15] = rk[ 7] ^ rk[14];
- rk += 8;
- }
- }
- return 0;
-}
-
-
-/*
- Expand the cipher key into the decryption key schedule.
-
- RETURN
- The number of rounds for the given cipher key size.
-*/
-
-int rijndaelKeySetupDec(uint32 rk[/*4*(Nr + 1)*/], const uint8 cipherKey[],
- int keyBits)
-{
- int nr, i, j;
- uint32 temp;
-
- /* expand the cipher key: */
- nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits);
- /* invert the order of the round keys: */
- for (i = 0, j = 4*nr; i < j; i += 4, j -= 4)
- {
- temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
- temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
- temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
- temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
- }
- /*
- Apply the inverse MixColumn transform to all round keys but the first
- and the last:
- */
- for (i = 1; i < nr; i++)
- {
- rk += 4;
-
- rk[0]= (
- Td0[Te4[(rk[0] >> 24) ] & 0xff] ^
- Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
- Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^
- Td3[Te4[(rk[0] ) & 0xff] & 0xff]);
-
- rk[1]= (Td0[Te4[(rk[1] >> 24) ] & 0xff] ^
- Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
- Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^
- Td3[Te4[(rk[1] ) & 0xff] & 0xff]);
-
- rk[2]= (Td0[Te4[(rk[2] >> 24) ] & 0xff] ^
- Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
- Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^
- Td3[Te4[(rk[2] ) & 0xff] & 0xff]);
-
- rk[3]= (Td0[Te4[(rk[3] >> 24) ] & 0xff] ^
- Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
- Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^
- Td3[Te4[(rk[3] ) & 0xff] & 0xff]);
- }
- return nr;
-}
-
-
-void rijndaelEncrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr,
- const uint8 pt[16], uint8 ct[16])
-{
- uint32 s0, s1, s2, s3, t0, t1, t2, t3;
-#ifndef FULL_UNROLL
- int r;
-#endif /* FULL_UNROLL */
-
- /* map byte array block to cipher state and add initial round key: */
- s0 = GETuint32(pt ) ^ rk[0];
- s1 = GETuint32(pt + 4) ^ rk[1];
- s2 = GETuint32(pt + 8) ^ rk[2];
- s3 = GETuint32(pt + 12) ^ rk[3];
-
-#ifdef FULL_UNROLL
- /* round 1: */
- t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
- ^ Te3[s3 & 0xff] ^ rk[ 4]);
- t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
- ^ Te3[s0 & 0xff] ^ rk[ 5]);
- t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
- ^ Te3[s1 & 0xff] ^ rk[ 6]);
- t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
- ^ Te3[s2 & 0xff] ^ rk[ 7]);
-
- /* round 2: */
- s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff]
- ^ Te3[t3 & 0xff] ^ rk[ 8]);
- s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff]
- ^ Te3[t0 & 0xff] ^ rk[ 9]);
- s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff]
- ^ Te3[t1 & 0xff] ^ rk[10]);
- s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff]
- ^ Te3[t2 & 0xff] ^ rk[11]);
-
- /* round 3: */
- t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
- ^ Te3[s3 & 0xff] ^ rk[12]);
- t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
- ^ Te3[s0 & 0xff] ^ rk[13]);
- t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
- ^ Te3[s1 & 0xff] ^ rk[14]);
- t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
- ^ Te3[s2 & 0xff] ^ rk[15]);
-
- /* round 4: */
- s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff]
- ^ Te3[t3 & 0xff] ^ rk[16]);
- s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff]
- ^ Te3[t0 & 0xff] ^ rk[17]);
- s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff]
- ^ Te3[t1 & 0xff] ^ rk[18]);
- s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff]
- ^ Te3[t2 & 0xff] ^ rk[19]);
-
- /* round 5: */
- t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
- ^ Te3[s3 & 0xff] ^ rk[20]);
- t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
- ^ Te3[s0 & 0xff] ^ rk[21]);
- t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
- ^ Te3[s1 & 0xff] ^ rk[22]);
- t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
- ^ Te3[s2 & 0xff] ^ rk[23]);
-
- /* round 6: */
- s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff]
- ^ Te3[t3 & 0xff] ^ rk[24]);
- s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff]
- ^ Te3[t0 & 0xff] ^ rk[25]);
- s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff]
- ^ Te3[t1 & 0xff] ^ rk[26]);
- s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff]
- ^ Te3[t2 & 0xff] ^ rk[27]);
-
- /* round 7: */
- t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
- ^ Te3[s3 & 0xff] ^ rk[28]);
- t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
- ^ Te3[s0 & 0xff] ^ rk[29]);
- t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
- ^ Te3[s1 & 0xff] ^ rk[30]);
- t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
- ^ Te3[s2 & 0xff] ^ rk[31]);
-
- /* round 8: */
- s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff]
- ^ Te3[t3 & 0xff] ^ rk[32]);
- s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff]
- ^ Te3[t0 & 0xff] ^ rk[33]);
- s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff]
- ^ Te3[t1 & 0xff] ^ rk[34]);
- s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff]
- ^ Te3[t2 & 0xff] ^ rk[35]);
-
- /* round 9: */
- t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
- ^ Te3[s3 & 0xff] ^ rk[36]);
- t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
- ^ Te3[s0 & 0xff] ^ rk[37]);
- t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
- ^ Te3[s1 & 0xff] ^ rk[38]);
- t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
- ^ Te3[s2 & 0xff] ^ rk[39]);
-
- if (Nr > 10)
- {
- /* round 10: */
- s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff]
- ^ Te3[t3 & 0xff] ^ rk[40]);
- s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff]
- ^ Te3[t0 & 0xff] ^ rk[41]);
- s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff]
- ^ Te3[t1 & 0xff] ^ rk[42]);
- s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff]
- ^ Te3[t2 & 0xff] ^ rk[43]);
-
- /* round 11: */
- t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
- ^ Te3[s3 & 0xff] ^ rk[44]);
- t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
- ^ Te3[s0 & 0xff] ^ rk[45]);
- t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
- ^ Te3[s1 & 0xff] ^ rk[46]);
- t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
- ^ Te3[s2 & 0xff] ^ rk[47]);
-
- if (Nr > 12)
- {
- /* round 12: */
- s0= (Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff]
- ^ Te3[t3 & 0xff] ^ rk[48]);
- s1= (Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff]
- ^ Te3[t0 & 0xff] ^ rk[49]);
- s2= (Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff]
- ^ Te3[t1 & 0xff] ^ rk[50]);
- s3= (Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff]
- ^ Te3[t2 & 0xff] ^ rk[51]);
-
- /* round 13: */
- t0= (Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff]
- ^ Te3[s3 & 0xff] ^ rk[52]);
- t1= (Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff]
- ^ Te3[s0 & 0xff] ^ rk[53]);
- t2= (Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff]
- ^ Te3[s1 & 0xff] ^ rk[54]);
- t3= (Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff]
- ^ Te3[s2 & 0xff] ^ rk[55]);
- }
- }
- rk += Nr << 2;
-#else /* !FULL_UNROLL */
-
- /* Nr - 1 full rounds: */
-
- r = Nr >> 1;
- for (;;)
- {
- t0= (Te0[(s0 >> 24) ] ^
- Te1[(s1 >> 16) & 0xff] ^
- Te2[(s2 >> 8) & 0xff] ^
- Te3[(s3 ) & 0xff] ^
- rk[4]);
-
- t1= (Te0[(s1 >> 24) ] ^
- Te1[(s2 >> 16) & 0xff] ^
- Te2[(s3 >> 8) & 0xff] ^
- Te3[(s0 ) & 0xff] ^
- rk[5]);
-
- t2= (Te0[(s2 >> 24) ] ^
- Te1[(s3 >> 16) & 0xff] ^
- Te2[(s0 >> 8) & 0xff] ^
- Te3[(s1 ) & 0xff] ^
- rk[6]);
-
- t3= (Te0[(s3 >> 24) ] ^
- Te1[(s0 >> 16) & 0xff] ^
- Te2[(s1 >> 8) & 0xff] ^
- Te3[(s2 ) & 0xff] ^
- rk[7]);
-
- rk+= 8;
- if (--r == 0)
- break;
-
- s0= (Te0[(t0 >> 24) ] ^
- Te1[(t1 >> 16) & 0xff] ^
- Te2[(t2 >> 8) & 0xff] ^
- Te3[(t3 ) & 0xff] ^
- rk[0]);
-
- s1= (Te0[(t1 >> 24) ] ^
- Te1[(t2 >> 16) & 0xff] ^
- Te2[(t3 >> 8) & 0xff] ^
- Te3[(t0 ) & 0xff] ^
- rk[1]);
-
- s2= (Te0[(t2 >> 24) ] ^
- Te1[(t3 >> 16) & 0xff] ^
- Te2[(t0 >> 8) & 0xff] ^
- Te3[(t1 ) & 0xff] ^
- rk[2]);
-
- s3= (Te0[(t3 >> 24) ] ^
- Te1[(t0 >> 16) & 0xff] ^
- Te2[(t1 >> 8) & 0xff] ^
- Te3[(t2 ) & 0xff] ^
- rk[3]);
- }
-#endif /* FULL_UNROLL */
-
- /* Apply last round and map cipher state to byte array block: */
- s0= ((Te4[(t0 >> 24) ] & 0xff000000) ^
- (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(t3 ) & 0xff] & 0x000000ff) ^
- rk[0]);
- PUTuint32(ct , s0);
-
- s1= ((Te4[(t1 >> 24) ] & 0xff000000) ^
- (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(t0 ) & 0xff] & 0x000000ff) ^
- rk[1]);
- PUTuint32(ct + 4, s1);
-
- s2= ((Te4[(t2 >> 24) ] & 0xff000000) ^
- (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(t1 ) & 0xff] & 0x000000ff) ^
- rk[2]);
- PUTuint32(ct + 8, s2);
-
- s3= ((Te4[(t3 >> 24) ] & 0xff000000) ^
- (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(t2 ) & 0xff] & 0x000000ff) ^
- rk[3]);
- PUTuint32(ct + 12, s3);
-}
-
-
-void rijndaelDecrypt(const uint32 rk[/*4*(Nr + 1)*/], int Nr,
- const uint8 ct[16], uint8 pt[16])
-{
- uint32 s0, s1, s2, s3, t0, t1, t2, t3;
-#ifndef FULL_UNROLL
- int r;
-#endif /* FULL_UNROLL */
-
- /* Map byte array block to cipher state and add initial round key: */
-
- s0 = GETuint32(ct ) ^ rk[0];
- s1 = GETuint32(ct + 4) ^ rk[1];
- s2 = GETuint32(ct + 8) ^ rk[2];
- s3 = GETuint32(ct + 12) ^ rk[3];
-
-#ifdef FULL_UNROLL
- /* round 1: */
- t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
- ^ Td3[s1 & 0xff] ^ rk[ 4]);
- t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
- ^ Td3[s2 & 0xff] ^ rk[ 5]);
- t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
- ^ Td3[s3 & 0xff] ^ rk[ 6]);
- t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
- ^ Td3[s0 & 0xff] ^ rk[ 7]);
-
- /* round 2: */
- s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff]
- ^ Td3[t1 & 0xff] ^ rk[ 8]);
- s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff]
- ^ Td3[t2 & 0xff] ^ rk[ 9]);
- s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff]
- ^ Td3[t3 & 0xff] ^ rk[10]);
- s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff]
- ^ Td3[t0 & 0xff] ^ rk[11]);
-
- /* round 3: */
- t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
- ^ Td3[s1 & 0xff] ^ rk[12]);
- t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
- ^ Td3[s2 & 0xff] ^ rk[13]);
- t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
- ^ Td3[s3 & 0xff] ^ rk[14]);
- t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
- ^ Td3[s0 & 0xff] ^ rk[15]);
-
- /* round 4: */
- s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff]
- ^ Td3[t1 & 0xff] ^ rk[16]);
- s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff]
- ^ Td3[t2 & 0xff] ^ rk[17]);
- s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff]
- ^ Td3[t3 & 0xff] ^ rk[18]);
- s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff]
- ^ Td3[t0 & 0xff] ^ rk[19]);
-
- /* round 5: */
- t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
- ^ Td3[s1 & 0xff] ^ rk[20]);
- t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
- ^ Td3[s2 & 0xff] ^ rk[21]);
- t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
- ^ Td3[s3 & 0xff] ^ rk[22]);
- t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
- ^ Td3[s0 & 0xff] ^ rk[23]);
-
- /* round 6: */
- s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff]
- ^ Td3[t1 & 0xff] ^ rk[24]);
- s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff]
- ^ Td3[t2 & 0xff] ^ rk[25]);
- s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff]
- ^ Td3[t3 & 0xff] ^ rk[26]);
- s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff]
- ^ Td3[t0 & 0xff] ^ rk[27]);
-
- /* round 7: */
- t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
- ^ Td3[s1 & 0xff] ^ rk[28]);
- t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
- ^ Td3[s2 & 0xff] ^ rk[29]);
- t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
- ^ Td3[s3 & 0xff] ^ rk[30]);
- t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
- ^ Td3[s0 & 0xff] ^ rk[31]);
-
- /* round 8: */
- s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff]
- ^ Td3[t1 & 0xff] ^ rk[32]);
- s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff]
- ^ Td3[t2 & 0xff] ^ rk[33]);
- s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff]
- ^ Td3[t3 & 0xff] ^ rk[34]);
- s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff]
- ^ Td3[t0 & 0xff] ^ rk[35]);
-
- /* round 9: */
- t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
- ^ Td3[s1 & 0xff] ^ rk[36]);
- t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
- ^ Td3[s2 & 0xff] ^ rk[37]);
- t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
- ^ Td3[s3 & 0xff] ^ rk[38]);
- t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
- ^ Td3[s0 & 0xff] ^ rk[39]);
-
- if (Nr > 10)
- {
- /* round 10: */
- s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff]
- ^ Td3[t1 & 0xff] ^ rk[40]);
- s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff]
- ^ Td3[t2 & 0xff] ^ rk[41]);
- s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff]
- ^ Td3[t3 & 0xff] ^ rk[42]);
- s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff]
- ^ Td3[t0 & 0xff] ^ rk[43]);
-
- /* round 11: */
- t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
- ^ Td3[s1 & 0xff] ^ rk[44]);
- t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
- ^ Td3[s2 & 0xff] ^ rk[45]);
- t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
- ^ Td3[s3 & 0xff] ^ rk[46]);
- t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
- ^ Td3[s0 & 0xff] ^ rk[47]);
-
- if (Nr > 12)
- {
- /* round 12: */
- s0= (Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff]
- ^ Td3[t1 & 0xff] ^ rk[48]);
- s1= (Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff]
- ^ Td3[t2 & 0xff] ^ rk[49]);
- s2= (Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff]
- ^ Td3[t3 & 0xff] ^ rk[50]);
- s3= (Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff]
- ^ Td3[t0 & 0xff] ^ rk[51]);
-
- /* round 13: */
- t0= (Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff]
- ^ Td3[s1 & 0xff] ^ rk[52]);
- t1= (Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff]
- ^ Td3[s2 & 0xff] ^ rk[53]);
- t2= (Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff]
- ^ Td3[s3 & 0xff] ^ rk[54]);
- t3= (Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff]
- ^ Td3[s0 & 0xff] ^ rk[55]);
- }
- }
- rk += Nr << 2;
-#else /* !FULL_UNROLL */
-
- /* Nr - 1 full rounds: */
- r= (Nr >> 1);
- for (;;)
- {
- t0= (Td0[(s0 >> 24) ] ^
- Td1[(s3 >> 16) & 0xff] ^
- Td2[(s2 >> 8) & 0xff] ^
- Td3[(s1 ) & 0xff] ^
- rk[4]);
-
- t1= (Td0[(s1 >> 24) ] ^
- Td1[(s0 >> 16) & 0xff] ^
- Td2[(s3 >> 8) & 0xff] ^
- Td3[(s2 ) & 0xff] ^
- rk[5]);
-
- t2= (Td0[(s2 >> 24) ] ^
- Td1[(s1 >> 16) & 0xff] ^
- Td2[(s0 >> 8) & 0xff] ^
- Td3[(s3 ) & 0xff] ^
- rk[6]);
-
- t3= (Td0[(s3 >> 24) ] ^
- Td1[(s2 >> 16) & 0xff] ^
- Td2[(s1 >> 8) & 0xff] ^
- Td3[(s0 ) & 0xff] ^
- rk[7]);
-
- rk+= 8;
- if (--r == 0)
- break;
-
- s0= (Td0[(t0 >> 24) ] ^
- Td1[(t3 >> 16) & 0xff] ^
- Td2[(t2 >> 8) & 0xff] ^
- Td3[(t1 ) & 0xff] ^
- rk[0]);
-
- s1= (Td0[(t1 >> 24) ] ^
- Td1[(t0 >> 16) & 0xff] ^
- Td2[(t3 >> 8) & 0xff] ^
- Td3[(t2 ) & 0xff] ^
- rk[1]);
-
- s2= (Td0[(t2 >> 24) ] ^
- Td1[(t1 >> 16) & 0xff] ^
- Td2[(t0 >> 8) & 0xff] ^
- Td3[(t3 ) & 0xff] ^
- rk[2]);
-
- s3= (Td0[(t3 >> 24) ] ^
- Td1[(t2 >> 16) & 0xff] ^
- Td2[(t1 >> 8) & 0xff] ^
- Td3[(t0 ) & 0xff] ^
- rk[3]);
- }
-
-#endif /* FULL_UNROLL */
-
- /* Apply last round and map cipher state to byte array block: */
-
- s0= ((Td4[(t0 >> 24) ] & 0xff000000) ^
- (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(t1 ) & 0xff] & 0x000000ff) ^
- rk[0]);
- PUTuint32(pt , s0);
-
- s1= ((Td4[(t1 >> 24) ] & 0xff000000) ^
- (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(t2 ) & 0xff] & 0x000000ff) ^
- rk[1]);
- PUTuint32(pt + 4, s1);
-
- s2= ((Td4[(t2 >> 24) ] & 0xff000000) ^
- (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(t3 ) & 0xff] & 0x000000ff) ^
- rk[2]);
- PUTuint32(pt + 8, s2);
-
- s3= ((Td4[(t3 >> 24) ] & 0xff000000) ^
- (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(t0 ) & 0xff] & 0x000000ff) ^
- rk[3]);
- PUTuint32(pt + 12, s3);
-}
diff --git a/dep/mysqllite/mysys/sha1.c b/dep/mysqllite/mysys/sha1.c
deleted file mode 100644
index e5b33a9ad13..00000000000
--- a/dep/mysqllite/mysys/sha1.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/* Copyright (c) 2002, 2004, 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-/*
- Original Source from: http://www.faqs.org/rfcs/rfc3174.html
-
- Copyright (C) The Internet Society (2001). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assigns.
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
- Acknowledgement
- Funding for the RFC Editor function is currently provided by the
- Internet Society.
-
- DESCRIPTION
- This file implements the Secure Hashing Algorithm 1 as
- defined in FIPS PUB 180-1 published April 17, 1995.
-
- The SHA-1, produces a 160-bit message digest for a given data
- stream. It should take about 2**n steps to find a message with the
- same digest as a given message and 2**(n/2) to find any two
- messages with the same digest, when n is the digest size in bits.
- Therefore, this algorithm can serve as a means of providing a
- "fingerprint" for a message.
-
- PORTABILITY ISSUES
- SHA-1 is defined in terms of 32-bit "words". This code uses
- <stdint.h> (included via "sha1.h" to define 32 and 8 bit unsigned
- integer types. If your C compiler does not support 32 bit unsigned
- integers, this code is not appropriate.
-
- CAVEATS
- SHA-1 is designed to work with messages less than 2^64 bits long.
- Although SHA-1 allows a message digest to be generated for messages
- of any number of bits less than 2^64, this implementation only
- works with messages with a length that is a multiple of the size of
- an 8-bit character.
-
- CHANGES
- 2002 by Peter Zaitsev to
- - fit to new prototypes according to MySQL standard
- - Some optimizations
- - All checking is now done in debug only mode
- - More comments
-*/
-
-#include "my_global.h"
-#include "m_string.h"
-#include "sha1.h"
-
-/*
- Define the SHA1 circular left shift macro
-*/
-
-#define SHA1CircularShift(bits,word) \
- (((word) << (bits)) | ((word) >> (32-(bits))))
-
-/* Local Function Prototyptes */
-static void SHA1PadMessage(SHA1_CONTEXT*);
-static void SHA1ProcessMessageBlock(SHA1_CONTEXT*);
-
-
-/*
- Initialize SHA1Context
-
- SYNOPSIS
- mysql_sha1_reset()
- context [in/out] The context to reset.
-
- DESCRIPTION
- This function will initialize the SHA1Context in preparation
- for computing a new SHA1 message digest.
-
- RETURN
- SHA_SUCCESS ok
- != SHA_SUCCESS sha Error Code.
-*/
-
-
-const uint32 sha_const_key[5]=
-{
- 0x67452301,
- 0xEFCDAB89,
- 0x98BADCFE,
- 0x10325476,
- 0xC3D2E1F0
-};
-
-
-int mysql_sha1_reset(SHA1_CONTEXT *context)
-{
-#ifndef DBUG_OFF
- if (!context)
- return SHA_NULL;
-#endif
-
- context->Length = 0;
- context->Message_Block_Index = 0;
-
- context->Intermediate_Hash[0] = sha_const_key[0];
- context->Intermediate_Hash[1] = sha_const_key[1];
- context->Intermediate_Hash[2] = sha_const_key[2];
- context->Intermediate_Hash[3] = sha_const_key[3];
- context->Intermediate_Hash[4] = sha_const_key[4];
-
- context->Computed = 0;
- context->Corrupted = 0;
-
- return SHA_SUCCESS;
-}
-
-
-/*
- Return the 160-bit message digest into the array provided by the caller
-
- SYNOPSIS
- mysql_sha1_result()
- context [in/out] The context to use to calculate the SHA-1 hash.
- Message_Digest: [out] Where the digest is returned.
-
- DESCRIPTION
- NOTE: The first octet of hash is stored in the 0th element,
- the last octet of hash in the 19th element.
-
- RETURN
- SHA_SUCCESS ok
- != SHA_SUCCESS sha Error Code.
-*/
-
-int mysql_sha1_result(SHA1_CONTEXT *context,
- uint8 Message_Digest[SHA1_HASH_SIZE])
-{
- int i;
-
-#ifndef DBUG_OFF
- if (!context || !Message_Digest)
- return SHA_NULL;
-
- if (context->Corrupted)
- return context->Corrupted;
-#endif
-
- if (!context->Computed)
- {
- SHA1PadMessage(context);
- /* message may be sensitive, clear it out */
- bzero((char*) context->Message_Block,64);
- context->Length = 0; /* and clear length */
- context->Computed = 1;
- }
-
- for (i = 0; i < SHA1_HASH_SIZE; i++)
- Message_Digest[i] = (int8)((context->Intermediate_Hash[i>>2] >> 8
- * ( 3 - ( i & 0x03 ) )));
- return SHA_SUCCESS;
-}
-
-
-/*
- Accepts an array of octets as the next portion of the message.
-
- SYNOPSIS
- mysql_sha1_input()
- context [in/out] The SHA context to update
- message_array An array of characters representing the next portion
- of the message.
- length The length of the message in message_array
-
- RETURN
- SHA_SUCCESS ok
- != SHA_SUCCESS sha Error Code.
-*/
-
-int mysql_sha1_input(SHA1_CONTEXT *context, const uint8 *message_array,
- unsigned length)
-{
- if (!length)
- return SHA_SUCCESS;
-
-#ifndef DBUG_OFF
- /* We assume client konows what it is doing in non-debug mode */
- if (!context || !message_array)
- return SHA_NULL;
- if (context->Computed)
- return (context->Corrupted= SHA_STATE_ERROR);
- if (context->Corrupted)
- return context->Corrupted;
-#endif
-
- while (length--)
- {
- context->Message_Block[context->Message_Block_Index++]=
- (*message_array & 0xFF);
- context->Length += 8; /* Length is in bits */
-
-#ifndef DBUG_OFF
- /*
- Then we're not debugging we assume we never will get message longer
- 2^64 bits.
- */
- if (context->Length == 0)
- return (context->Corrupted= 1); /* Message is too long */
-#endif
-
- if (context->Message_Block_Index == 64)
- {
- SHA1ProcessMessageBlock(context);
- }
- message_array++;
- }
- return SHA_SUCCESS;
-}
-
-
-/*
- Process the next 512 bits of the message stored in the Message_Block array.
-
- SYNOPSIS
- SHA1ProcessMessageBlock()
-
- DESCRIPTION
- Many of the variable names in this code, especially the single
- character names, were used because those were the names used in
- the publication.
-*/
-
-/* Constants defined in SHA-1 */
-static const uint32 K[]=
-{
- 0x5A827999,
- 0x6ED9EBA1,
- 0x8F1BBCDC,
- 0xCA62C1D6
-};
-
-
-static void SHA1ProcessMessageBlock(SHA1_CONTEXT *context)
-{
- int t; /* Loop counter */
- uint32 temp; /* Temporary word value */
- uint32 W[80]; /* Word sequence */
- uint32 A, B, C, D, E; /* Word buffers */
- int idx;
-
- /*
- Initialize the first 16 words in the array W
- */
-
- for (t = 0; t < 16; t++)
- {
- idx=t*4;
- W[t] = context->Message_Block[idx] << 24;
- W[t] |= context->Message_Block[idx + 1] << 16;
- W[t] |= context->Message_Block[idx + 2] << 8;
- W[t] |= context->Message_Block[idx + 3];
- }
-
-
- for (t = 16; t < 80; t++)
- {
- W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
- }
-
- A = context->Intermediate_Hash[0];
- B = context->Intermediate_Hash[1];
- C = context->Intermediate_Hash[2];
- D = context->Intermediate_Hash[3];
- E = context->Intermediate_Hash[4];
-
- for (t = 0; t < 20; t++)
- {
- temp= SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
- E = D;
- D = C;
- C = SHA1CircularShift(30,B);
- B = A;
- A = temp;
- }
-
- for (t = 20; t < 40; t++)
- {
- temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
- E = D;
- D = C;
- C = SHA1CircularShift(30,B);
- B = A;
- A = temp;
- }
-
- for (t = 40; t < 60; t++)
- {
- temp= (SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] +
- K[2]);
- E = D;
- D = C;
- C = SHA1CircularShift(30,B);
- B = A;
- A = temp;
- }
-
- for (t = 60; t < 80; t++)
- {
- temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
- E = D;
- D = C;
- C = SHA1CircularShift(30,B);
- B = A;
- A = temp;
- }
-
- context->Intermediate_Hash[0] += A;
- context->Intermediate_Hash[1] += B;
- context->Intermediate_Hash[2] += C;
- context->Intermediate_Hash[3] += D;
- context->Intermediate_Hash[4] += E;
-
- context->Message_Block_Index = 0;
-}
-
-
-/*
- Pad message
-
- SYNOPSIS
- SHA1PadMessage()
- context: [in/out] The context to pad
-
- DESCRIPTION
- According to the standard, the message must be padded to an even
- 512 bits. The first padding bit must be a '1'. The last 64 bits
- represent the length of the original message. All bits in between
- should be 0. This function will pad the message according to
- those rules by filling the Message_Block array accordingly. It
- will also call the ProcessMessageBlock function provided
- appropriately. When it returns, it can be assumed that the message
- digest has been computed.
-
-*/
-
-static void SHA1PadMessage(SHA1_CONTEXT *context)
-{
- /*
- Check to see if the current message block is too small to hold
- the initial padding bits and length. If so, we will pad the
- block, process it, and then continue padding into a second
- block.
- */
-
- int i=context->Message_Block_Index;
-
- if (i > 55)
- {
- context->Message_Block[i++] = 0x80;
- bzero((char*) &context->Message_Block[i],
- sizeof(context->Message_Block[0])*(64-i));
- context->Message_Block_Index=64;
-
- /* This function sets context->Message_Block_Index to zero */
- SHA1ProcessMessageBlock(context);
-
- bzero((char*) &context->Message_Block[0],
- sizeof(context->Message_Block[0])*56);
- context->Message_Block_Index=56;
- }
- else
- {
- context->Message_Block[i++] = 0x80;
- bzero((char*) &context->Message_Block[i],
- sizeof(context->Message_Block[0])*(56-i));
- context->Message_Block_Index=56;
- }
-
- /*
- Store the message length as the last 8 octets
- */
-
- context->Message_Block[56] = (int8) (context->Length >> 56);
- context->Message_Block[57] = (int8) (context->Length >> 48);
- context->Message_Block[58] = (int8) (context->Length >> 40);
- context->Message_Block[59] = (int8) (context->Length >> 32);
- context->Message_Block[60] = (int8) (context->Length >> 24);
- context->Message_Block[61] = (int8) (context->Length >> 16);
- context->Message_Block[62] = (int8) (context->Length >> 8);
- context->Message_Block[63] = (int8) (context->Length);
-
- SHA1ProcessMessageBlock(context);
-}
diff --git a/dep/mysqllite/mysys/stacktrace.c b/dep/mysqllite/mysys/stacktrace.c
deleted file mode 100644
index 48cdaaa6c91..00000000000
--- a/dep/mysqllite/mysys/stacktrace.c
+++ /dev/null
@@ -1,714 +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 <my_global.h>
-#include <my_stacktrace.h>
-
-#ifndef __WIN__
-#include <signal.h>
-#include <my_pthread.h>
-#include <m_string.h>
-#ifdef HAVE_STACKTRACE
-#include <unistd.h>
-#include <strings.h>
-
-#ifdef __linux__
-#include <ctype.h> /* isprint */
-#include <sys/syscall.h> /* SYS_gettid */
-#endif
-
-#if HAVE_EXECINFO_H
-#include <execinfo.h>
-#endif
-
-#define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end)
-
-static char *heap_start;
-
-#ifdef HAVE_BSS_START
-extern char *__bss_start;
-#endif
-
-void my_init_stacktrace()
-{
-#ifdef HAVE_BSS_START
- heap_start = (char*) &__bss_start;
-#endif
-}
-
-#ifdef __linux__
-
-static void print_buffer(char *buffer, size_t count)
-{
- for (; count && *buffer; --count)
- {
- int c= (int) *buffer++;
- fputc(isprint(c) ? c : ' ', stderr);
- }
-}
-
-/**
- Access the pages of this process through /proc/self/task/<tid>/mem
- in order to safely print the contents of a memory address range.
-
- @param addr The address at the start of the memory region.
- @param max_len The length of the memory region.
-
- @return Zero on success.
-*/
-static int safe_print_str(const char *addr, int max_len)
-{
- int fd;
- pid_t tid;
- off_t offset;
- ssize_t nbytes= 0;
- size_t total, count;
- char buf[256];
-
- tid= (pid_t) syscall(SYS_gettid);
-
- sprintf(buf, "/proc/self/task/%d/mem", tid);
-
- if ((fd= open(buf, O_RDONLY)) < 0)
- return -1;
-
- /* Ensure that off_t can hold a pointer. */
- compile_time_assert(sizeof(off_t) >= sizeof(intptr));
-
- total= max_len;
- offset= (intptr) addr;
-
- /* Read up to the maximum number of bytes. */
- while (total)
- {
- count= min(sizeof(buf), total);
-
- if ((nbytes= pread(fd, buf, count, offset)) < 0)
- {
- /* Just in case... */
- if (errno == EINTR)
- continue;
- else
- break;
- }
-
- /* Advance offset into memory. */
- total-= nbytes;
- offset+= nbytes;
- addr+= nbytes;
-
- /* Output the printable characters. */
- print_buffer(buf, nbytes);
-
- /* Break if less than requested... */
- if ((count - nbytes))
- break;
- }
-
- /* Output a new line if something was printed. */
- if (total != (size_t) max_len)
- fputc('\n', stderr);
-
- if (nbytes == -1)
- fprintf(stderr, "Can't read from address %p: %m.\n", addr);
-
- close(fd);
-
- return 0;
-}
-
-#endif
-
-void my_safe_print_str(const char* val, int max_len)
-{
- char *heap_end;
-
-#ifdef __linux__
- if (!safe_print_str(val, max_len))
- return;
-#endif
-
- heap_end= (char*) sbrk(0);
-
- if (!PTR_SANE(val))
- {
- fprintf(stderr, "is an invalid pointer\n");
- return;
- }
-
- for (; max_len && PTR_SANE(val) && *val; --max_len)
- fputc(*val++, stderr);
- fputc('\n', stderr);
-}
-
-#if defined(HAVE_PRINTSTACK)
-
-/* Use Solaris' symbolic stack trace routine. */
-#include <ucontext.h>
-
-void my_print_stacktrace(uchar* stack_bottom __attribute__((unused)),
- ulong thread_stack __attribute__((unused)))
-{
- if (printstack(fileno(stderr)) == -1)
- fprintf(stderr, "Error when traversing the stack, stack appears corrupt.\n");
- else
- fprintf(stderr,
- "Please read "
- "http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n"
- "and follow instructions on how to resolve the stack trace.\n"
- "Resolved stack trace is much more helpful in diagnosing the\n"
- "problem, so please do resolve it\n");
-}
-
-#elif HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD)
-
-#if BACKTRACE_DEMANGLE
-
-char __attribute__ ((weak)) *
-my_demangle(const char *mangled_name __attribute__((unused)),
- int *status __attribute__((unused)))
-{
- return NULL;
-}
-
-static void my_demangle_symbols(char **addrs, int n)
-{
- int status, i;
- char *begin, *end, *demangled;
-
- for (i= 0; i < n; i++)
- {
- demangled= NULL;
- begin= strchr(addrs[i], '(');
- end= begin ? strchr(begin, '+') : NULL;
-
- if (begin && end)
- {
- *begin++= *end++= '\0';
- demangled= my_demangle(begin, &status);
- if (!demangled || status)
- {
- demangled= NULL;
- begin[-1]= '(';
- end[-1]= '+';
- }
- }
-
- if (demangled)
- fprintf(stderr, "%s(%s+%s\n", addrs[i], demangled, end);
- else
- fprintf(stderr, "%s\n", addrs[i]);
- }
-}
-
-#endif /* BACKTRACE_DEMANGLE */
-
-void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack)
-{
- void *addrs[128];
- char **strings= NULL;
- int n = backtrace(addrs, array_elements(addrs));
- fprintf(stderr, "stack_bottom = %p thread_stack 0x%lx\n",
- stack_bottom, thread_stack);
-#if BACKTRACE_DEMANGLE
- if ((strings= backtrace_symbols(addrs, n)))
- {
- my_demangle_symbols(strings, n);
- free(strings);
- }
-#endif
-#if HAVE_BACKTRACE_SYMBOLS_FD
- if (!strings)
- {
- backtrace_symbols_fd(addrs, n, fileno(stderr));
- }
-#endif
-}
-
-#elif defined(TARGET_OS_LINUX)
-
-#ifdef __i386__
-#define SIGRETURN_FRAME_OFFSET 17
-#endif
-
-#ifdef __x86_64__
-#define SIGRETURN_FRAME_OFFSET 23
-#endif
-
-#if defined(__alpha__) && defined(__GNUC__)
-/*
- The only way to backtrace without a symbol table on alpha
- is to find stq fp,N(sp), and the first byte
- of the instruction opcode will give us the value of N. From this
- we can find where the old value of fp is stored
-*/
-
-#define MAX_INSTR_IN_FUNC 10000
-
-inline uchar** find_prev_fp(uint32* pc, uchar** fp)
-{
- int i;
- for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc)
- {
- uchar* p = (uchar*)pc;
- if (p[2] == 222 && p[3] == 35)
- {
- return (uchar**)((uchar*)fp - *(short int*)p);
- }
- }
- return 0;
-}
-
-inline uint32* find_prev_pc(uint32* pc, uchar** fp)
-{
- int i;
- for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc)
- {
- char* p = (char*)pc;
- if (p[1] == 0 && p[2] == 94 && p[3] == -73)
- {
- uint32* prev_pc = (uint32*)*((fp+p[0]/sizeof(fp)));
- return prev_pc;
- }
- }
- return 0;
-}
-#endif /* defined(__alpha__) && defined(__GNUC__) */
-
-void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack)
-{
- uchar** fp;
- uint frame_count = 0, sigreturn_frame_count;
-#if defined(__alpha__) && defined(__GNUC__)
- uint32* pc;
-#endif
- LINT_INIT(fp);
-
-
-#ifdef __i386__
- __asm __volatile__ ("movl %%ebp,%0"
- :"=r"(fp)
- :"r"(fp));
-#endif
-#ifdef __x86_64__
- __asm __volatile__ ("movq %%rbp,%0"
- :"=r"(fp)
- :"r"(fp));
-#endif
-#if defined(__alpha__) && defined(__GNUC__)
- __asm __volatile__ ("mov $30,%0"
- :"=r"(fp)
- :"r"(fp));
-#endif
- if (!fp)
- {
- fprintf(stderr, "frame pointer is NULL, did you compile with\n\
--fomit-frame-pointer? Aborting backtrace!\n");
- return;
- }
-
- if (!stack_bottom || (uchar*) stack_bottom > (uchar*) &fp)
- {
- ulong tmp= min(0x10000,thread_stack);
- /* Assume that the stack starts at the previous even 65K */
- stack_bottom= (uchar*) (((ulong) &fp + tmp) &
- ~(ulong) 0xFFFF);
- fprintf(stderr, "Cannot determine thread, fp=%p, backtrace may not be correct.\n", fp);
- }
- if (fp > (uchar**) stack_bottom ||
- fp < (uchar**) stack_bottom - thread_stack)
- {
- fprintf(stderr, "Bogus stack limit or frame pointer,\
- fp=%p, stack_bottom=%p, thread_stack=%ld, aborting backtrace.\n",
- fp, stack_bottom, thread_stack);
- return;
- }
-
- fprintf(stderr, "Stack range sanity check OK, backtrace follows:\n");
-#if defined(__alpha__) && defined(__GNUC__)
- fprintf(stderr, "Warning: Alpha stacks are difficult -\
- will be taking some wild guesses, stack trace may be incorrect or \
- terminate abruptly\n");
- /* On Alpha, we need to get pc */
- __asm __volatile__ ("bsr %0, do_next; do_next: "
- :"=r"(pc)
- :"r"(pc));
-#endif /* __alpha__ */
-
- /* We are 1 frame above signal frame with NPTL and 2 frames above with LT */
- sigreturn_frame_count = thd_lib_detected == THD_LIB_LT ? 2 : 1;
-
- while (fp < (uchar**) stack_bottom)
- {
-#if defined(__i386__) || defined(__x86_64__)
- uchar** new_fp = (uchar**)*fp;
- fprintf(stderr, "%p\n", frame_count == sigreturn_frame_count ?
- *(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1));
-#endif /* defined(__386__) || defined(__x86_64__) */
-
-#if defined(__alpha__) && defined(__GNUC__)
- uchar** new_fp = find_prev_fp(pc, fp);
- if (frame_count == sigreturn_frame_count - 1)
- {
- new_fp += 90;
- }
-
- if (fp && pc)
- {
- pc = find_prev_pc(pc, fp);
- if (pc)
- fprintf(stderr, "%p\n", pc);
- else
- {
- fprintf(stderr, "Not smart enough to deal with the rest\
- of this stack\n");
- goto end;
- }
- }
- else
- {
- fprintf(stderr, "Not smart enough to deal with the rest of this stack\n");
- goto end;
- }
-#endif /* defined(__alpha__) && defined(__GNUC__) */
- if (new_fp <= fp )
- {
- fprintf(stderr, "New value of fp=%p failed sanity check,\
- terminating stack trace!\n", new_fp);
- goto end;
- }
- fp = new_fp;
- ++frame_count;
- }
-
- fprintf(stderr, "Stack trace seems successful - bottom reached\n");
-
-end:
- fprintf(stderr,
- "Please read http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n"
- "and follow instructions on how to resolve the stack trace.\n"
- "Resolved stack trace is much more helpful in diagnosing the\n"
- "problem, so please do resolve it\n");
-}
-#endif /* TARGET_OS_LINUX */
-#endif /* HAVE_STACKTRACE */
-
-/* Produce a core for the thread */
-void my_write_core(int sig)
-{
-#ifdef HAVE_gcov
- extern void __gcov_flush(void);
-#endif
- signal(sig, SIG_DFL);
-#ifdef HAVE_gcov
- /*
- For GCOV build, crashing will prevent the writing of code coverage
- information from this process, causing gcov output to be incomplete.
- So we force the writing of coverage information here before terminating.
- */
- __gcov_flush();
-#endif
- pthread_kill(pthread_self(), sig);
-#if defined(P_MYID) && !defined(SCO)
- /* On Solaris, the above kill is not enough */
- sigsend(P_PID,P_MYID,sig);
-#endif
-}
-
-#else /* __WIN__*/
-
-#include <dbghelp.h>
-#include <tlhelp32.h>
-#if _MSC_VER
-#pragma comment(lib, "dbghelp")
-#endif
-
-static EXCEPTION_POINTERS *exception_ptrs;
-
-#define MODULE64_SIZE_WINXP 576
-#define STACKWALK_MAX_FRAMES 64
-
-void my_init_stacktrace()
-{
-}
-
-
-void my_set_exception_pointers(EXCEPTION_POINTERS *ep)
-{
- exception_ptrs = ep;
-}
-
-/*
- Appends directory to symbol path.
-*/
-static void add_to_symbol_path(char *path, size_t path_buffer_size,
- char *dir, size_t dir_buffer_size)
-{
- strcat_s(dir, dir_buffer_size, ";");
- if (!strstr(path, dir))
- {
- strcat_s(path, path_buffer_size, dir);
- }
-}
-
-/*
- Get symbol path - semicolon-separated list of directories to search for debug
- symbols. We expect PDB in the same directory as corresponding exe or dll,
- so the path is build from directories of the loaded modules. If environment
- variable _NT_SYMBOL_PATH is set, it's value appended to the symbol search path
-*/
-static void get_symbol_path(char *path, size_t size)
-{
- HANDLE hSnap;
- char *envvar;
- char *p;
-#ifndef DBUG_OFF
- static char pdb_debug_dir[MAX_PATH + 7];
-#endif
-
- path[0]= '\0';
-
-#ifndef DBUG_OFF
- /*
- Add "debug" subdirectory of the application directory, sometimes PDB will
- placed here by installation.
- */
- GetModuleFileName(NULL, pdb_debug_dir, MAX_PATH);
- p= strrchr(pdb_debug_dir, '\\');
- if(p)
- {
- *p= 0;
- strcat_s(pdb_debug_dir, sizeof(pdb_debug_dir), "\\debug;");
- add_to_symbol_path(path, size, pdb_debug_dir, sizeof(pdb_debug_dir));
- }
-#endif
-
- /*
- Enumerate all modules, and add their directories to the path.
- Avoid duplicate entries.
- */
- hSnap= CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
- if (hSnap != INVALID_HANDLE_VALUE)
- {
- BOOL ret;
- MODULEENTRY32 mod;
- mod.dwSize= sizeof(MODULEENTRY32);
- for (ret= Module32First(hSnap, &mod); ret; ret= Module32Next(hSnap, &mod))
- {
- char *module_dir= mod.szExePath;
- p= strrchr(module_dir,'\\');
- if (!p)
- {
- /*
- Path separator was not found. Not known to happen, if ever happens,
- will indicate current directory.
- */
- module_dir[0]= '.';
- module_dir[1]= '\0';
- }
- else
- {
- *p= '\0';
- }
- add_to_symbol_path(path, size, module_dir,sizeof(mod.szExePath));
- }
- CloseHandle(hSnap);
- }
-
-
- /* Add _NT_SYMBOL_PATH, if present. */
- envvar= getenv("_NT_SYMBOL_PATH");
- if(envvar)
- {
- strcat_s(path, size, envvar);
- }
-}
-
-#define MAX_SYMBOL_PATH 32768
-
-/* Platform SDK in VS2003 does not have definition for SYMOPT_NO_PROMPTS*/
-#ifndef SYMOPT_NO_PROMPTS
-#define SYMOPT_NO_PROMPTS 0
-#endif
-
-void my_print_stacktrace(uchar* unused1, ulong unused2)
-{
- HANDLE hProcess= GetCurrentProcess();
- HANDLE hThread= GetCurrentThread();
- static IMAGEHLP_MODULE64 module= {sizeof(module)};
- static IMAGEHLP_SYMBOL64_PACKAGE package;
- DWORD64 addr;
- DWORD machine;
- int i;
- CONTEXT context;
- STACKFRAME64 frame={0};
- static char symbol_path[MAX_SYMBOL_PATH];
-
- if(!exception_ptrs)
- return;
-
- /* Copy context, as stackwalking on original will unwind the stack */
- context = *(exception_ptrs->ContextRecord);
- /*Initialize symbols.*/
- SymSetOptions(SYMOPT_LOAD_LINES|SYMOPT_NO_PROMPTS|SYMOPT_DEFERRED_LOADS|SYMOPT_DEBUG);
- get_symbol_path(symbol_path, sizeof(symbol_path));
- SymInitialize(hProcess, symbol_path, TRUE);
-
- /*Prepare stackframe for the first StackWalk64 call*/
- frame.AddrFrame.Mode= frame.AddrPC.Mode= frame.AddrStack.Mode= AddrModeFlat;
-#if (defined _M_IX86)
- machine= IMAGE_FILE_MACHINE_I386;
- frame.AddrFrame.Offset= context.Ebp;
- frame.AddrPC.Offset= context.Eip;
- frame.AddrStack.Offset= context.Esp;
-#elif (defined _M_X64)
- machine = IMAGE_FILE_MACHINE_AMD64;
- frame.AddrFrame.Offset= context.Rbp;
- frame.AddrPC.Offset= context.Rip;
- frame.AddrStack.Offset= context.Rsp;
-#else
- /*There is currently no need to support IA64*/
-#pragma error ("unsupported architecture")
-#endif
-
- package.sym.SizeOfStruct= sizeof(package.sym);
- package.sym.MaxNameLength= sizeof(package.name);
-
- /*Walk the stack, output useful information*/
- for(i= 0; i< STACKWALK_MAX_FRAMES;i++)
- {
- DWORD64 function_offset= 0;
- DWORD line_offset= 0;
- IMAGEHLP_LINE64 line= {sizeof(line)};
- BOOL have_module= FALSE;
- BOOL have_symbol= FALSE;
- BOOL have_source= FALSE;
-
- if(!StackWalk64(machine, hProcess, hThread, &frame, &context, 0, 0, 0 ,0))
- break;
- addr= frame.AddrPC.Offset;
-
- have_module= SymGetModuleInfo64(hProcess,addr,&module);
-#ifdef _M_IX86
- if(!have_module)
- {
- /*
- ModuleInfo structure has been "compatibly" extended in releases after XP,
- and its size was increased. To make XP dbghelp.dll function
- happy, pretend passing the old structure.
- */
- module.SizeOfStruct= MODULE64_SIZE_WINXP;
- have_module= SymGetModuleInfo64(hProcess, addr, &module);
- }
-#endif
-
- have_symbol= SymGetSymFromAddr64(hProcess, addr, &function_offset,
- &(package.sym));
- have_source= SymGetLineFromAddr64(hProcess, addr, &line_offset, &line);
-
- fprintf(stderr, "%p ", addr);
- if(have_module)
- {
- char *base_image_name= strrchr(module.ImageName, '\\');
- if(base_image_name)
- base_image_name++;
- else
- base_image_name= module.ImageName;
- fprintf(stderr, "%s!", base_image_name);
- }
- if(have_symbol)
- fprintf(stderr, "%s()", package.sym.Name);
- else if(have_module)
- fprintf(stderr, "???");
-
- if(have_source)
- {
- char *base_file_name= strrchr(line.FileName, '\\');
- if(base_file_name)
- base_file_name++;
- else
- base_file_name= line.FileName;
- fprintf(stderr,"[%s:%u]", base_file_name, line.LineNumber);
- }
- fprintf(stderr, "\n");
- }
- fflush(stderr);
-}
-
-
-/*
- Write dump. The dump is created in current directory,
- file name is constructed from executable name plus
- ".dmp" extension
-*/
-void my_write_core(int unused)
-{
- char path[MAX_PATH];
- char dump_fname[MAX_PATH]= "core.dmp";
- MINIDUMP_EXCEPTION_INFORMATION info;
- HANDLE hFile;
-
- if(!exception_ptrs)
- return;
-
- info.ExceptionPointers= exception_ptrs;
- info.ClientPointers= FALSE;
- info.ThreadId= GetCurrentThreadId();
-
- if(GetModuleFileName(NULL, path, sizeof(path)))
- {
- _splitpath(path, NULL, NULL,dump_fname,NULL);
- strncat(dump_fname, ".dmp", sizeof(dump_fname));
- }
-
- hFile= CreateFile(dump_fname, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, 0);
- if(hFile)
- {
- /* Create minidump */
- if(MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
- hFile, MiniDumpNormal, &info, 0, 0))
- {
- fprintf(stderr, "Minidump written to %s\n",
- _fullpath(path, dump_fname, sizeof(path)) ? path : dump_fname);
- }
- else
- {
- fprintf(stderr,"MiniDumpWriteDump() failed, last error %u\n",
- GetLastError());
- }
- CloseHandle(hFile);
- }
- else
- {
- fprintf(stderr, "CreateFile(%s) failed, last error %u\n", dump_fname,
- GetLastError());
- }
- fflush(stderr);
-}
-
-
-void my_safe_print_str(const char *val, int len)
-{
- __try
- {
- fprintf(stderr,"=%.*s\n", len, val);
- }
- __except(EXCEPTION_EXECUTE_HANDLER)
- {
- fprintf(stderr,"is an invalid string pointer\n");
- }
-}
-#endif /*__WIN__*/
diff --git a/dep/mysqllite/mysys/string.c b/dep/mysqllite/mysys/string.c
deleted file mode 100644
index b1eded0664c..00000000000
--- a/dep/mysqllite/mysys/string.c
+++ /dev/null
@@ -1,182 +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 */
-
-/*
- Code for handling strings with can grow dynamicly.
- Copyright Monty Program KB.
- By monty.
-*/
-
-#include "mysys_priv.h"
-#include <m_string.h>
-
-my_bool init_dynamic_string(DYNAMIC_STRING *str, const char *init_str,
- size_t init_alloc, size_t alloc_increment)
-{
- size_t length;
- DBUG_ENTER("init_dynamic_string");
-
- if (!alloc_increment)
- alloc_increment=128;
- length=1;
- if (init_str && (length= strlen(init_str)+1) < init_alloc)
- init_alloc=((length+alloc_increment-1)/alloc_increment)*alloc_increment;
- if (!init_alloc)
- init_alloc=alloc_increment;
-
- if (!(str->str=(char*) my_malloc(init_alloc,MYF(MY_WME))))
- DBUG_RETURN(TRUE);
- str->length=length-1;
- if (init_str)
- memcpy(str->str,init_str,length);
- str->max_length=init_alloc;
- str->alloc_increment=alloc_increment;
- DBUG_RETURN(FALSE);
-}
-
-
-my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str)
-{
- uint length=0;
- DBUG_ENTER("dynstr_set");
-
- if (init_str && (length= (uint) strlen(init_str)+1) > str->max_length)
- {
- str->max_length=((length+str->alloc_increment-1)/str->alloc_increment)*
- str->alloc_increment;
- if (!str->max_length)
- str->max_length=str->alloc_increment;
- if (!(str->str=(char*) my_realloc(str->str,str->max_length,MYF(MY_WME))))
- DBUG_RETURN(TRUE);
- }
- if (init_str)
- {
- str->length=length-1;
- memcpy(str->str,init_str,length);
- }
- else
- str->length=0;
- DBUG_RETURN(FALSE);
-}
-
-
-my_bool dynstr_realloc(DYNAMIC_STRING *str, size_t additional_size)
-{
- DBUG_ENTER("dynstr_realloc");
-
- if (!additional_size) DBUG_RETURN(FALSE);
- if (str->length + additional_size > str->max_length)
- {
- str->max_length=((str->length + additional_size+str->alloc_increment-1)/
- str->alloc_increment)*str->alloc_increment;
- if (!(str->str=(char*) my_realloc(str->str,str->max_length,MYF(MY_WME))))
- DBUG_RETURN(TRUE);
- }
- DBUG_RETURN(FALSE);
-}
-
-
-my_bool dynstr_append(DYNAMIC_STRING *str, const char *append)
-{
- return dynstr_append_mem(str,append,(uint) strlen(append));
-}
-
-
-my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
- size_t length)
-{
- char *new_ptr;
- if (str->length+length >= str->max_length)
- {
- size_t new_length=(str->length+length+str->alloc_increment)/
- str->alloc_increment;
- new_length*=str->alloc_increment;
- if (!(new_ptr=(char*) my_realloc(str->str,new_length,MYF(MY_WME))))
- return TRUE;
- str->str=new_ptr;
- str->max_length=new_length;
- }
- memcpy(str->str + str->length,append,length);
- str->length+=length;
- str->str[str->length]=0; /* Safety for C programs */
- return FALSE;
-}
-
-
-my_bool dynstr_trunc(DYNAMIC_STRING *str, size_t n)
-{
- str->length-=n;
- str->str[str->length]= '\0';
- return FALSE;
-}
-
-/*
- Concatenates any number of strings, escapes any OS quote in the result then
- surround the whole affair in another set of quotes which is finally appended
- to specified DYNAMIC_STRING. This function is especially useful when
- building strings to be executed with the system() function.
-
- @param str Dynamic String which will have addtional strings appended.
- @param append String to be appended.
- @param ... Optional. Additional string(s) to be appended.
-
- @note The final argument in the list must be NullS even if no additional
- options are passed.
-
- @return True = Success.
-*/
-
-my_bool dynstr_append_os_quoted(DYNAMIC_STRING *str, const char *append, ...)
-{
-#ifdef __WIN__
- const char *quote_str= "\"";
- const uint quote_len= 1;
-#else
- const char *quote_str= "\'";
- const uint quote_len= 1;
-#endif /* __WIN__ */
- my_bool ret= TRUE;
- va_list dirty_text;
-
- ret&= dynstr_append_mem(str, quote_str, quote_len); /* Leading quote */
- va_start(dirty_text, append);
- while (append != NullS)
- {
- const char *cur_pos= append;
- const char *next_pos= cur_pos;
-
- /* Search for quote in each string and replace with escaped quote */
- while(*(next_pos= strcend(cur_pos, quote_str[0])) != '\0')
- {
- ret&= dynstr_append_mem(str, cur_pos, (uint) (next_pos - cur_pos));
- ret&= dynstr_append_mem(str ,"\\", 1);
- ret&= dynstr_append_mem(str, quote_str, quote_len);
- cur_pos= next_pos + 1;
- }
- ret&= dynstr_append_mem(str, cur_pos, (uint) (next_pos - cur_pos));
- append= va_arg(dirty_text, char *);
- }
- va_end(dirty_text);
- ret&= dynstr_append_mem(str, quote_str, quote_len); /* Trailing quote */
-
- return ret;
-}
-
-
-void dynstr_free(DYNAMIC_STRING *str)
-{
- my_free(str->str);
- str->str= NULL;
-}
diff --git a/dep/mysqllite/mysys/thr_alarm.c b/dep/mysqllite/mysys/thr_alarm.c
deleted file mode 100644
index 2e427f96bdd..00000000000
--- a/dep/mysqllite/mysys/thr_alarm.c
+++ /dev/null
@@ -1,972 +0,0 @@
-/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 */
-
-/* To avoid problems with alarms in debug code, we disable DBUG here */
-#define FORCE_DBUG_OFF
-#include "mysys_priv.h"
-#include <my_global.h>
-
-#if !defined(DONT_USE_THR_ALARM)
-#include <errno.h>
-#include <my_pthread.h>
-#include <signal.h>
-#include <my_sys.h>
-#include <m_string.h>
-#include <queues.h>
-#include "thr_alarm.h"
-
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h> /* AIX needs this for fd_set */
-#endif
-
-#ifndef ETIME
-#define ETIME ETIMEDOUT
-#endif
-
-uint thr_client_alarm;
-static int alarm_aborted=1; /* No alarm thread */
-my_bool thr_alarm_inited= 0;
-volatile my_bool alarm_thread_running= 0;
-time_t next_alarm_expire_time= ~ (time_t) 0;
-static sig_handler process_alarm_part2(int sig);
-
-#if !defined(__WIN__)
-
-static mysql_mutex_t LOCK_alarm;
-static mysql_cond_t COND_alarm;
-static sigset_t full_signal_set;
-static QUEUE alarm_queue;
-static uint max_used_alarms=0;
-pthread_t alarm_thread;
-
-#ifdef USE_ALARM_THREAD
-static void *alarm_handler(void *arg);
-#define reschedule_alarms() mysql_cond_signal(&COND_alarm)
-#else
-#define reschedule_alarms() pthread_kill(alarm_thread,THR_SERVER_ALARM)
-#endif
-
-static sig_handler thread_alarm(int sig __attribute__((unused)));
-
-static int compare_ulong(void *not_used __attribute__((unused)),
- uchar *a_ptr,uchar* b_ptr)
-{
- ulong a=*((ulong*) a_ptr),b= *((ulong*) b_ptr);
- return (a < b) ? -1 : (a == b) ? 0 : 1;
-}
-
-void init_thr_alarm(uint max_alarms)
-{
- sigset_t s;
- DBUG_ENTER("init_thr_alarm");
- alarm_aborted=0;
- next_alarm_expire_time= ~ (time_t) 0;
- init_queue(&alarm_queue,max_alarms+1,offsetof(ALARM,expire_time),0,
- compare_ulong,NullS);
- sigfillset(&full_signal_set); /* Neaded to block signals */
- mysql_mutex_init(key_LOCK_alarm, &LOCK_alarm, MY_MUTEX_INIT_FAST);
- mysql_cond_init(key_COND_alarm, &COND_alarm, NULL);
- if (thd_lib_detected == THD_LIB_LT)
- thr_client_alarm= SIGALRM;
- else
- thr_client_alarm= SIGUSR1;
-#ifndef USE_ALARM_THREAD
- if (thd_lib_detected != THD_LIB_LT)
-#endif
- {
- my_sigset(thr_client_alarm, thread_alarm);
- }
- sigemptyset(&s);
- sigaddset(&s, THR_SERVER_ALARM);
- alarm_thread=pthread_self();
-#if defined(USE_ALARM_THREAD)
- {
- pthread_attr_t thr_attr;
- pthread_attr_init(&thr_attr);
- pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);
- pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
- pthread_attr_setstacksize(&thr_attr,8196);
- mysql_thread_create(key_thread_alarm,
- &alarm_thread, &thr_attr, alarm_handler, NULL);
- pthread_attr_destroy(&thr_attr);
- }
-#elif defined(USE_ONE_SIGNAL_HAND)
- pthread_sigmask(SIG_BLOCK, &s, NULL); /* used with sigwait() */
- if (thd_lib_detected == THD_LIB_LT)
- {
- my_sigset(thr_client_alarm, process_alarm); /* Linuxthreads */
- pthread_sigmask(SIG_UNBLOCK, &s, NULL);
- }
-#else
- my_sigset(THR_SERVER_ALARM, process_alarm);
- pthread_sigmask(SIG_UNBLOCK, &s, NULL);
-#endif
- DBUG_VOID_RETURN;
-}
-
-
-void resize_thr_alarm(uint max_alarms)
-{
- mysql_mutex_lock(&LOCK_alarm);
- /*
- It's ok not to shrink the queue as there may be more pending alarms than
- than max_alarms
- */
- if (alarm_queue.elements < max_alarms)
- resize_queue(&alarm_queue,max_alarms+1);
- mysql_mutex_unlock(&LOCK_alarm);
-}
-
-
-/*
- Request alarm after sec seconds.
-
- SYNOPSIS
- thr_alarm()
- alrm Pointer to alarm detection
- alarm_data Structure to store in alarm queue
-
- NOTES
- This function can't be called from the alarm-handling thread.
-
- RETURN VALUES
- 0 ok
- 1 If no more alarms are allowed (aborted by process)
-
- Stores in first argument a pointer to a non-zero int which is set to 0
- when the alarm has been given
-*/
-
-my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
-{
- time_t now;
-#ifndef USE_ONE_SIGNAL_HAND
- sigset_t old_mask;
-#endif
- my_bool reschedule;
- struct st_my_thread_var *current_my_thread_var= my_thread_var;
- DBUG_ENTER("thr_alarm");
- DBUG_PRINT("enter",("thread: %s sec: %d",my_thread_name(),sec));
-
- now= my_time(0);
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
-#endif
- mysql_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */
- if (alarm_aborted > 0)
- { /* No signal thread */
- DBUG_PRINT("info", ("alarm aborted"));
- *alrm= 0; /* No alarm */
- mysql_mutex_unlock(&LOCK_alarm);
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
-#endif
- DBUG_RETURN(1);
- }
- if (alarm_aborted < 0)
- sec= 1; /* Abort mode */
-
- if (alarm_queue.elements >= max_used_alarms)
- {
- if (alarm_queue.elements == alarm_queue.max_elements)
- {
- DBUG_PRINT("info", ("alarm queue full"));
- fprintf(stderr,"Warning: thr_alarm queue is full\n");
- *alrm= 0; /* No alarm */
- mysql_mutex_unlock(&LOCK_alarm);
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
-#endif
- DBUG_RETURN(1);
- }
- max_used_alarms=alarm_queue.elements+1;
- }
- reschedule= (ulong) next_alarm_expire_time > (ulong) now + sec;
- if (!alarm_data)
- {
- if (!(alarm_data=(ALARM*) my_malloc(sizeof(ALARM),MYF(MY_WME))))
- {
- DBUG_PRINT("info", ("failed my_malloc()"));
- *alrm= 0; /* No alarm */
- mysql_mutex_unlock(&LOCK_alarm);
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
-#endif
- DBUG_RETURN(1);
- }
- alarm_data->malloced=1;
- }
- else
- alarm_data->malloced=0;
- alarm_data->expire_time=now+sec;
- alarm_data->alarmed=0;
- alarm_data->thread= current_my_thread_var->pthread_self;
- alarm_data->thread_id= current_my_thread_var->id;
- queue_insert(&alarm_queue,(uchar*) alarm_data);
-
- /* Reschedule alarm if the current one has more than sec left */
- if (reschedule)
- {
- DBUG_PRINT("info", ("reschedule"));
- if (pthread_equal(pthread_self(),alarm_thread))
- {
- alarm(sec); /* purecov: inspected */
- next_alarm_expire_time= now + sec;
- }
- else
- reschedule_alarms(); /* Reschedule alarms */
- }
- mysql_mutex_unlock(&LOCK_alarm);
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
-#endif
- (*alrm)= &alarm_data->alarmed;
- DBUG_RETURN(0);
-}
-
-
-/*
- Remove alarm from list of alarms
-*/
-
-void thr_end_alarm(thr_alarm_t *alarmed)
-{
- ALARM *alarm_data;
-#ifndef USE_ONE_SIGNAL_HAND
- sigset_t old_mask;
-#endif
- uint i, found=0;
- DBUG_ENTER("thr_end_alarm");
-
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
-#endif
- mysql_mutex_lock(&LOCK_alarm);
-
- alarm_data= (ALARM*) ((uchar*) *alarmed - offsetof(ALARM,alarmed));
- for (i=0 ; i < alarm_queue.elements ; i++)
- {
- if ((ALARM*) queue_element(&alarm_queue,i) == alarm_data)
- {
- queue_remove(&alarm_queue,i),MYF(0);
- if (alarm_data->malloced)
- my_free(alarm_data);
- found++;
-#ifdef DBUG_OFF
- break;
-#endif
- }
- }
- DBUG_ASSERT(!*alarmed || found == 1);
- if (!found)
- {
- if (*alarmed)
- fprintf(stderr,"Warning: Didn't find alarm 0x%lx in queue of %d alarms\n",
- (long) *alarmed, alarm_queue.elements);
- DBUG_PRINT("warning",("Didn't find alarm 0x%lx in queue\n",
- (long) *alarmed));
- }
- mysql_mutex_unlock(&LOCK_alarm);
-#ifndef USE_ONE_SIGNAL_HAND
- pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
-#endif
- DBUG_VOID_RETURN;
-}
-
-/*
- Come here when some alarm in queue is due.
- Mark all alarms with are finnished in list.
- Shedule alarms to be sent again after 1-10 sec (many alarms at once)
- If alarm_aborted is set then all alarms are given and resent
- every second.
-*/
-
-sig_handler process_alarm(int sig __attribute__((unused)))
-{
- sigset_t old_mask;
-/*
- This must be first as we can't call DBUG inside an alarm for a normal thread
-*/
-
- if (thd_lib_detected == THD_LIB_LT &&
- !pthread_equal(pthread_self(),alarm_thread))
- {
-#if defined(MAIN) && !defined(__bsdi__)
- printf("thread_alarm in process_alarm\n"); fflush(stdout);
-#endif
-#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY
- my_sigset(thr_client_alarm, process_alarm); /* int. thread system calls */
-#endif
- return;
- }
-
- /*
- We have to do do the handling of the alarm in a sub function,
- because otherwise we would get problems with two threads calling
- DBUG_... functions at the same time (as two threads may call
- process_alarm() at the same time
- */
-
-#ifndef USE_ALARM_THREAD
- pthread_sigmask(SIG_SETMASK,&full_signal_set,&old_mask);
- mysql_mutex_lock(&LOCK_alarm);
-#endif
- process_alarm_part2(sig);
-#ifndef USE_ALARM_THREAD
-#if defined(SIGNAL_HANDLER_RESET_ON_DELIVERY) && !defined(USE_ONE_SIGNAL_HAND)
- my_sigset(THR_SERVER_ALARM,process_alarm);
-#endif
- mysql_mutex_unlock(&LOCK_alarm);
- pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
-#endif
- return;
-}
-
-
-static sig_handler process_alarm_part2(int sig __attribute__((unused)))
-{
- ALARM *alarm_data;
- DBUG_ENTER("process_alarm");
- DBUG_PRINT("info",("sig: %d active alarms: %d",sig,alarm_queue.elements));
-
-#if defined(MAIN) && !defined(__bsdi__)
- printf("process_alarm\n"); fflush(stdout);
-#endif
- if (alarm_queue.elements)
- {
- if (alarm_aborted)
- {
- uint i;
- for (i=0 ; i < alarm_queue.elements ;)
- {
- alarm_data=(ALARM*) queue_element(&alarm_queue,i);
- alarm_data->alarmed=1; /* Info to thread */
- if (pthread_equal(alarm_data->thread,alarm_thread) ||
- pthread_kill(alarm_data->thread, thr_client_alarm))
- {
-#ifdef MAIN
- printf("Warning: pthread_kill couldn't find thread!!!\n");
-#endif
- queue_remove(&alarm_queue,i); /* No thread. Remove alarm */
- }
- else
- i++; /* Signal next thread */
- }
-#ifndef USE_ALARM_THREAD
- if (alarm_queue.elements)
- alarm(1); /* Signal soon again */
-#endif
- }
- else
- {
- ulong now=(ulong) my_time(0);
- ulong next=now+10-(now%10);
- while ((alarm_data=(ALARM*) queue_top(&alarm_queue))->expire_time <= now)
- {
- alarm_data->alarmed=1; /* Info to thread */
- DBUG_PRINT("info",("sending signal to waiting thread"));
- if (pthread_equal(alarm_data->thread,alarm_thread) ||
- pthread_kill(alarm_data->thread, thr_client_alarm))
- {
-#ifdef MAIN
- printf("Warning: pthread_kill couldn't find thread!!!\n");
-#endif
- queue_remove(&alarm_queue,0); /* No thread. Remove alarm */
- if (!alarm_queue.elements)
- break;
- }
- else
- {
- alarm_data->expire_time=next;
- queue_replaced(&alarm_queue);
- }
- }
-#ifndef USE_ALARM_THREAD
- if (alarm_queue.elements)
- {
-#ifdef __bsdi__
- alarm(0); /* Remove old alarm */
-#endif
- alarm((uint) (alarm_data->expire_time-now));
- next_alarm_expire_time= alarm_data->expire_time;
- }
-#endif
- }
- }
- else
- {
- /*
- Ensure that next time we call thr_alarm(), we will schedule a new alarm
- */
- next_alarm_expire_time= ~(time_t) 0;
- }
- DBUG_VOID_RETURN;
-}
-
-
-/*
- Schedule all alarms now and optionally free all structures
-
- SYNPOSIS
- end_thr_alarm()
- free_structures Set to 1 if we should free memory used for
- the alarm queue.
- When we call this we should KNOW that there
- is no active alarms
- IMPLEMENTATION
- Set alarm_abort to -1 which will change the behavior of alarms as follows:
- - All old alarms will be rescheduled at once
- - All new alarms will be rescheduled to one second
-*/
-
-void end_thr_alarm(my_bool free_structures)
-{
- DBUG_ENTER("end_thr_alarm");
- if (alarm_aborted != 1) /* If memory not freed */
- {
- mysql_mutex_lock(&LOCK_alarm);
- DBUG_PRINT("info",("Resheduling %d waiting alarms",alarm_queue.elements));
- alarm_aborted= -1; /* mark aborted */
- if (alarm_queue.elements || (alarm_thread_running && free_structures))
- {
- if (pthread_equal(pthread_self(),alarm_thread))
- alarm(1); /* Shut down everything soon */
- else
- reschedule_alarms();
- }
- if (free_structures)
- {
- struct timespec abstime;
-
- DBUG_ASSERT(!alarm_queue.elements);
-
- /* Wait until alarm thread dies */
- set_timespec(abstime, 10); /* Wait up to 10 seconds */
- while (alarm_thread_running)
- {
- int error= mysql_cond_timedwait(&COND_alarm, &LOCK_alarm, &abstime);
- if (error == ETIME || error == ETIMEDOUT)
- break; /* Don't wait forever */
- }
- delete_queue(&alarm_queue);
- alarm_aborted= 1;
- mysql_mutex_unlock(&LOCK_alarm);
- if (!alarm_thread_running) /* Safety */
- {
- mysql_mutex_destroy(&LOCK_alarm);
- mysql_cond_destroy(&COND_alarm);
- }
- }
- else
- mysql_mutex_unlock(&LOCK_alarm);
- }
- DBUG_VOID_RETURN;
-}
-
-
-/*
- Remove another thread from the alarm
-*/
-
-void thr_alarm_kill(my_thread_id thread_id)
-{
- uint i;
- if (alarm_aborted)
- return;
- mysql_mutex_lock(&LOCK_alarm);
- for (i=0 ; i < alarm_queue.elements ; i++)
- {
- if (((ALARM*) queue_element(&alarm_queue,i))->thread_id == thread_id)
- {
- ALARM *tmp=(ALARM*) queue_remove(&alarm_queue,i);
- tmp->expire_time=0;
- queue_insert(&alarm_queue,(uchar*) tmp);
- reschedule_alarms();
- break;
- }
- }
- mysql_mutex_unlock(&LOCK_alarm);
-}
-
-
-void thr_alarm_info(ALARM_INFO *info)
-{
- mysql_mutex_lock(&LOCK_alarm);
- info->next_alarm_time= 0;
- info->max_used_alarms= max_used_alarms;
- if ((info->active_alarms= alarm_queue.elements))
- {
- ulong now=(ulong) my_time(0);
- long time_diff;
- ALARM *alarm_data= (ALARM*) queue_top(&alarm_queue);
- time_diff= (long) (alarm_data->expire_time - now);
- info->next_alarm_time= (ulong) (time_diff < 0 ? 0 : time_diff);
- }
- mysql_mutex_unlock(&LOCK_alarm);
-}
-
-/*
- This is here for thread to get interruptet from read/write/fcntl
- ARGSUSED
-*/
-
-
-static sig_handler thread_alarm(int sig __attribute__((unused)))
-{
-#ifdef MAIN
- printf("thread_alarm\n"); fflush(stdout);
-#endif
-#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY
- my_sigset(sig,thread_alarm); /* int. thread system calls */
-#endif
-}
-
-
-#ifdef HAVE_TIMESPEC_TS_SEC
-#define tv_sec ts_sec
-#define tv_nsec ts_nsec
-#endif
-
-/* set up a alarm thread with uses 'sleep' to sleep between alarms */
-
-#ifdef USE_ALARM_THREAD
-static void *alarm_handler(void *arg __attribute__((unused)))
-{
- int error;
- struct timespec abstime;
-#ifdef MAIN
- puts("Starting alarm thread");
-#endif
- my_thread_init();
- alarm_thread_running= 1;
- mysql_mutex_lock(&LOCK_alarm);
- for (;;)
- {
- if (alarm_queue.elements)
- {
- ulong sleep_time,now= my_time(0);
- if (alarm_aborted)
- sleep_time=now+1;
- else
- sleep_time= ((ALARM*) queue_top(&alarm_queue))->expire_time;
- if (sleep_time > now)
- {
- abstime.tv_sec=sleep_time;
- abstime.tv_nsec=0;
- next_alarm_expire_time= sleep_time;
- if ((error= mysql_cond_timedwait(&COND_alarm, &LOCK_alarm, &abstime)) &&
- error != ETIME && error != ETIMEDOUT)
- {
-#ifdef MAIN
- printf("Got error: %d from ptread_cond_timedwait (errno: %d)\n",
- error,errno);
-#endif
- }
- }
- }
- else if (alarm_aborted == -1)
- break;
- else
- {
- next_alarm_expire_time= ~ (time_t) 0;
- if ((error= mysql_cond_wait(&COND_alarm, &LOCK_alarm)))
- {
-#ifdef MAIN
- printf("Got error: %d from ptread_cond_wait (errno: %d)\n",
- error,errno);
-#endif
- }
- }
- process_alarm(0);
- }
- bzero((char*) &alarm_thread,sizeof(alarm_thread)); /* For easy debugging */
- alarm_thread_running= 0;
- mysql_cond_signal(&COND_alarm);
- mysql_mutex_unlock(&LOCK_alarm);
- pthread_exit(0);
- return 0; /* Impossible */
-}
-#endif /* USE_ALARM_THREAD */
-
-/*****************************************************************************
- thr_alarm for win95
-*****************************************************************************/
-
-#else /* __WIN__ */
-
-void thr_alarm_kill(my_thread_id thread_id)
-{
- /* Can't do this yet */
-}
-
-sig_handler process_alarm(int sig __attribute__((unused)))
-{
- /* Can't do this yet */
-}
-
-
-my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm)
-{
- (*alrm)= &alarm->alarmed;
- if (alarm_aborted)
- {
- alarm->alarmed.crono=0;
- return 1;
- }
- if (!(alarm->alarmed.crono=SetTimer((HWND) NULL,0, sec*1000,
- (TIMERPROC) NULL)))
- return 1;
- return 0;
-}
-
-
-my_bool thr_got_alarm(thr_alarm_t *alrm_ptr)
-{
- thr_alarm_t alrm= *alrm_ptr;
- MSG msg;
- if (alrm->crono)
- {
- PeekMessage(&msg,NULL,WM_TIMER,WM_TIMER,PM_REMOVE) ;
- if (msg.message == WM_TIMER || alarm_aborted)
- {
- KillTimer(NULL, alrm->crono);
- alrm->crono = 0;
- }
- }
- return !alrm->crono || alarm_aborted;
-}
-
-
-void thr_end_alarm(thr_alarm_t *alrm_ptr)
-{
- thr_alarm_t alrm= *alrm_ptr;
- /* alrm may be zero if thr_alarm aborted with an error */
- if (alrm && alrm->crono)
-
- {
- KillTimer(NULL, alrm->crono);
- alrm->crono = 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)
-{
-}
-
-#endif /* __WIN__ */
-
-#endif
-
-/****************************************************************************
- Handling of test case (when compiled with -DMAIN)
-***************************************************************************/
-
-#ifdef MAIN
-#if !defined(DONT_USE_THR_ALARM)
-
-static mysql_cond_t COND_thread_count;
-static mysql_mutex_t LOCK_thread_count;
-static uint thread_count;
-
-#ifdef HPUX10
-typedef int * fd_set_ptr;
-#else
-typedef fd_set * fd_set_ptr;
-#endif /* HPUX10 */
-
-static void *test_thread(void *arg)
-{
- int i,param=*((int*) arg),wait_time,retry;
- time_t start_time;
- thr_alarm_t got_alarm;
- fd_set fd;
- FD_ZERO(&fd);
- my_thread_init();
- printf("Thread %d (%s) started\n",param,my_thread_name()); fflush(stdout);
- for (i=1 ; i <= 10 ; i++)
- {
- wait_time=param ? 11-i : i;
- start_time= my_time(0);
- if (thr_alarm(&got_alarm,wait_time,0))
- {
- printf("Thread: %s Alarms aborted\n",my_thread_name());
- break;
- }
- if (wait_time == 3)
- {
- printf("Thread: %s Simulation of no alarm needed\n",my_thread_name());
- fflush(stdout);
- }
- else
- {
- for (retry=0 ; !thr_got_alarm(&got_alarm) && retry < 10 ; retry++)
- {
- printf("Thread: %s Waiting %d sec\n",my_thread_name(),wait_time);
- select(0,(fd_set_ptr) &fd,0,0,0);
- }
- if (!thr_got_alarm(&got_alarm))
- {
- printf("Thread: %s didn't get an alarm. Aborting!\n",
- my_thread_name());
- break;
- }
- if (wait_time == 7)
- { /* Simulate alarm-miss */
- fd_set readFDs;
- uint max_connection=fileno(stdin);
- FD_ZERO(&readFDs);
- FD_SET(max_connection,&readFDs);
- retry=0;
- for (;;)
- {
- printf("Thread: %s Simulating alarm miss\n",my_thread_name());
- fflush(stdout);
- if (select(max_connection+1, (fd_set_ptr) &readFDs,0,0,0) < 0)
- {
- if (errno == EINTR)
- break; /* Got new interrupt */
- printf("Got errno: %d from select. Retrying..\n",errno);
- if (retry++ >= 3)
- {
- printf("Warning: Interrupt of select() doesn't set errno!\n");
- break;
- }
- }
- else /* This shouldn't happen */
- {
- if (!FD_ISSET(max_connection,&readFDs))
- {
- printf("Select interrupted, but errno not set\n");
- fflush(stdout);
- if (retry++ >= 3)
- break;
- continue;
- }
- (void) getchar(); /* Somebody was playing */
- }
- }
- }
- }
- printf("Thread: %s Slept for %d (%d) sec\n",my_thread_name(),
- (int) (my_time(0)-start_time), wait_time); fflush(stdout);
- thr_end_alarm(&got_alarm);
- fflush(stdout);
- }
- mysql_mutex_lock(&LOCK_thread_count);
- thread_count--;
- mysql_cond_signal(&COND_thread_count); /* Tell main we are ready */
- mysql_mutex_unlock(&LOCK_thread_count);
- free((uchar*) arg);
- return 0;
-}
-
-#ifdef USE_ONE_SIGNAL_HAND
-static sig_handler print_signal_warning(int sig)
-{
- printf("Warning: Got signal %d from thread %s\n",sig,my_thread_name());
- fflush(stdout);
-#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY
- my_sigset(sig,print_signal_warning); /* int. thread system calls */
-#endif
- if (sig == SIGALRM)
- alarm(2); /* reschedule alarm */
-}
-#endif /* USE_ONE_SIGNAL_HAND */
-
-
-static void *signal_hand(void *arg __attribute__((unused)))
-{
- sigset_t set;
- int sig,error,err_count=0;;
-
- my_thread_init();
- pthread_detach_this_thread();
- init_thr_alarm(10); /* Setup alarm handler */
- mysql_mutex_lock(&LOCK_thread_count); /* Required by bsdi */
- mysql_cond_signal(&COND_thread_count); /* Tell main we are ready */
- mysql_mutex_unlock(&LOCK_thread_count);
-
- sigemptyset(&set); /* Catch all signals */
- sigaddset(&set,SIGINT);
- sigaddset(&set,SIGQUIT);
- sigaddset(&set,SIGTERM);
- sigaddset(&set,SIGHUP);
-#ifdef SIGTSTP
- sigaddset(&set,SIGTSTP);
-#endif
-#ifdef USE_ONE_SIGNAL_HAND
- sigaddset(&set,THR_SERVER_ALARM); /* For alarms */
- puts("Starting signal and alarm handling thread");
-#else
- puts("Starting signal handling thread");
-#endif
- printf("server alarm: %d thread alarm: %d\n",
- THR_SERVER_ALARM, thr_client_alarm);
- DBUG_PRINT("info",("Starting signal and alarm handling thread"));
- for(;;)
- {
- while ((error=my_sigwait(&set,&sig)) == EINTR)
- printf("sigwait restarted\n");
- if (error)
- {
- fprintf(stderr,"Got error %d from sigwait\n",error);
- if (err_count++ > 5)
- exit(1); /* Too many errors in test */
- continue;
- }
-#ifdef USE_ONE_SIGNAL_HAND
- if (sig != THR_SERVER_ALARM)
-#endif
- printf("Main thread: Got signal %d\n",sig);
- switch (sig) {
- case SIGINT:
- case SIGQUIT:
- case SIGTERM:
- case SIGHUP:
- printf("Aborting nicely\n");
- end_thr_alarm(0);
- break;
-#ifdef SIGTSTP
- case SIGTSTP:
- printf("Aborting\n");
- exit(1);
- return 0; /* Keep some compilers happy */
-#endif
-#ifdef USE_ONE_SIGNAL_HAND
- case THR_SERVER_ALARM:
- process_alarm(sig);
- break;
-#endif
- }
- }
-}
-
-
-int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
-{
- pthread_t tid;
- pthread_attr_t thr_attr;
- int i,*param,error;
- sigset_t set;
- ALARM_INFO alarm_info;
- MY_INIT(argv[0]);
-
- if (argc > 1 && argv[1][0] == '-' && argv[1][1] == '#')
- {
- DBUG_PUSH(argv[1]+2);
- }
- mysql_mutex_init(0, &LOCK_thread_count, MY_MUTEX_INIT_FAST);
- mysql_cond_init(0, &COND_thread_count, NULL);
-
- /* Start a alarm handling thread */
- sigemptyset(&set);
- sigaddset(&set,SIGINT);
- sigaddset(&set,SIGQUIT);
- sigaddset(&set,SIGTERM);
- sigaddset(&set,SIGHUP);
- signal(SIGTERM,SIG_DFL); /* If it's blocked by parent */
-#ifdef SIGTSTP
- sigaddset(&set,SIGTSTP);
-#endif
- sigaddset(&set,THR_SERVER_ALARM);
- sigdelset(&set, thr_client_alarm);
- (void) pthread_sigmask(SIG_SETMASK,&set,NULL);
-
- pthread_attr_init(&thr_attr);
- pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);
- pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
- pthread_attr_setstacksize(&thr_attr,65536L);
-
- /* Start signal thread and wait for it to start */
- mysql_mutex_lock(&LOCK_thread_count);
- mysql_thread_create(0,
- &tid, &thr_attr, signal_hand, NULL);
- mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
- mysql_mutex_unlock(&LOCK_thread_count);
- DBUG_PRINT("info",("signal thread created"));
-
- thr_setconcurrency(3);
- pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);
- printf("Main thread: %s\n",my_thread_name());
- for (i=0 ; i < 2 ; i++)
- {
- param=(int*) malloc(sizeof(int));
- *param= i;
- mysql_mutex_lock(&LOCK_thread_count);
- if ((error= mysql_thread_create(0,
- &tid, &thr_attr, test_thread,
- (void*) param)))
- {
- printf("Can't create thread %d, error: %d\n",i,error);
- exit(1);
- }
- thread_count++;
- mysql_mutex_unlock(&LOCK_thread_count);
- }
-
- pthread_attr_destroy(&thr_attr);
- mysql_mutex_lock(&LOCK_thread_count);
- thr_alarm_info(&alarm_info);
- 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);
- while (thread_count)
- {
- mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
- if (thread_count == 1)
- {
- printf("Calling end_thr_alarm. This should cancel the last thread\n");
- end_thr_alarm(0);
- }
- }
- mysql_mutex_unlock(&LOCK_thread_count);
- 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);
- printf("Test succeeded\n");
- return 0;
-}
-
-#else /* !defined(DONT_USE_ALARM_THREAD) */
-
-int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
-{
- printf("thr_alarm disabled with DONT_USE_THR_ALARM\n");
- exit(1);
-}
-
-#endif /* !defined(DONT_USE_ALARM_THREAD) */
-#endif /* MAIN */
diff --git a/dep/mysqllite/mysys/thr_lock.c b/dep/mysqllite/mysys/thr_lock.c
deleted file mode 100644
index 2ab283e068d..00000000000
--- a/dep/mysqllite/mysys/thr_lock.c
+++ /dev/null
@@ -1,1688 +0,0 @@
-/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 */
-
-/*
-Read and write locks for Posix threads. All tread must acquire
-all locks it needs through thr_multi_lock() to avoid dead-locks.
-A lock consists of a master lock (THR_LOCK), and lock instances
-(THR_LOCK_DATA).
-Any thread can have any number of lock instances (read and write:s) on
-any lock. All lock instances must be freed.
-Locks are prioritized according to:
-
-The current lock types are:
-
-TL_READ # Low priority read
-TL_READ_WITH_SHARED_LOCKS
-TL_READ_HIGH_PRIORITY # High priority read
-TL_READ_NO_INSERT # Read without concurrent inserts
-TL_WRITE_ALLOW_WRITE # Write lock that allows other writers
-TL_WRITE_CONCURRENT_INSERT
- # Insert that can be mixed when selects
-TL_WRITE_DELAYED # Used by delayed insert
- # Allows lower locks to take over
-TL_WRITE_LOW_PRIORITY # Low priority write
-TL_WRITE # High priority write
-TL_WRITE_ONLY # High priority write
- # Abort all new lock request with an error
-
-Locks are prioritized according to:
-
-WRITE_ALLOW_WRITE, WRITE_CONCURRENT_INSERT, WRITE_DELAYED,
-WRITE_LOW_PRIORITY, READ, WRITE, READ_HIGH_PRIORITY and WRITE_ONLY
-
-Locks in the same privilege level are scheduled in first-in-first-out order.
-
-To allow concurrent read/writes locks, with 'WRITE_CONCURRENT_INSERT' one
-should put a pointer to the following functions in the lock structure:
-(If the pointer is zero (default), the function is not called)
-
-check_status:
- Before giving a lock of type TL_WRITE_CONCURRENT_INSERT,
- we check if this function exists and returns 0.
- If not, then the lock is upgraded to TL_WRITE_LOCK
- In MyISAM this is a simple check if the insert can be done
- at the end of the datafile.
-update_status:
- Before a write lock is released, this function is called.
- In MyISAM this functions updates the count and length of the datafile
-get_status:
- When one gets a lock this functions is called.
- In MyISAM this stores the number of rows and size of the datafile
- for concurrent reads.
-
-The lock algorithm allows one to have one TL_WRITE_CONCURRENT_INSERT or
-one TL_WRITE_DELAYED lock at the same time as multiple read locks.
-
-*/
-
-#if !defined(MAIN) && !defined(DBUG_OFF) && !defined(EXTRA_DEBUG)
-#define FORCE_DBUG_OFF
-#endif
-
-#include "mysys_priv.h"
-
-#include "thr_lock.h"
-#include <m_string.h>
-#include <errno.h>
-
-my_bool thr_lock_inited=0;
-ulong locks_immediate = 0L, locks_waited = 0L;
-enum thr_lock_type thr_upgraded_concurrent_insert_lock = TL_WRITE;
-
-/* The following constants are only for debug output */
-#define MAX_THREADS 100
-#define MAX_LOCKS 100
-
-
-LIST *thr_lock_thread_list; /* List of threads in use */
-ulong max_write_lock_count= ~(ulong) 0L;
-
-static void (*before_lock_wait)(void)= 0;
-static void (*after_lock_wait)(void)= 0;
-
-void thr_set_lock_wait_callback(void (*before_wait)(void),
- void (*after_wait)(void))
-{
- before_lock_wait= before_wait;
- after_lock_wait= after_wait;
-}
-
-static inline mysql_cond_t *get_cond(void)
-{
- return &my_thread_var->suspend;
-}
-
-/*
-** For the future (now the thread specific cond is alloced by my_pthread.c)
-*/
-
-my_bool init_thr_lock()
-{
- thr_lock_inited=1;
- return 0;
-}
-
-static inline my_bool
-thr_lock_owner_equal(THR_LOCK_INFO *rhs, THR_LOCK_INFO *lhs)
-{
- return rhs == lhs;
-}
-
-
-#ifdef EXTRA_DEBUG
-#define MAX_FOUND_ERRORS 10 /* Report 10 first errors */
-static uint found_errors=0;
-
-static int check_lock(struct st_lock_list *list, const char* lock_type,
- const char *where, my_bool same_owner, my_bool no_cond)
-{
- THR_LOCK_DATA *data,**prev;
- uint count=0;
- THR_LOCK_INFO *UNINIT_VAR(first_owner);
-
- prev= &list->data;
- if (list->data)
- {
- enum thr_lock_type last_lock_type=list->data->type;
-
- if (same_owner && list->data)
- first_owner= list->data->owner;
- for (data=list->data; data && count++ < MAX_LOCKS ; data=data->next)
- {
- if (data->type != last_lock_type)
- last_lock_type=TL_IGNORE;
- if (data->prev != prev)
- {
- fprintf(stderr,
- "Warning: prev link %d didn't point at previous lock at %s: %s\n",
- count, lock_type, where);
- return 1;
- }
- if (same_owner &&
- !thr_lock_owner_equal(data->owner, first_owner) &&
- last_lock_type != TL_WRITE_ALLOW_WRITE)
- {
- fprintf(stderr,
- "Warning: Found locks from different threads in %s: %s\n",
- lock_type,where);
- return 1;
- }
- if (no_cond && data->cond)
- {
- fprintf(stderr,
- "Warning: Found active lock with not reset cond %s: %s\n",
- lock_type,where);
- return 1;
- }
- prev= &data->next;
- }
- if (data)
- {
- fprintf(stderr,"Warning: found too many locks at %s: %s\n",
- lock_type,where);
- return 1;
- }
- }
- if (prev != list->last)
- {
- fprintf(stderr,"Warning: last didn't point at last lock at %s: %s\n",
- lock_type, where);
- return 1;
- }
- return 0;
-}
-
-
-static void check_locks(THR_LOCK *lock, const char *where,
- my_bool allow_no_locks)
-{
- uint old_found_errors=found_errors;
- DBUG_ENTER("check_locks");
-
- if (found_errors < MAX_FOUND_ERRORS)
- {
- if (check_lock(&lock->write,"write",where,1,1) |
- check_lock(&lock->write_wait,"write_wait",where,0,0) |
- check_lock(&lock->read,"read",where,0,1) |
- check_lock(&lock->read_wait,"read_wait",where,0,0))
- found_errors++;
-
- if (found_errors < MAX_FOUND_ERRORS)
- {
- uint count=0;
- THR_LOCK_DATA *data;
- for (data=lock->read.data ; data ; data=data->next)
- {
- if ((int) data->type == (int) TL_READ_NO_INSERT)
- count++;
- /* Protect against infinite loop. */
- DBUG_ASSERT(count <= lock->read_no_write_count);
- }
- if (count != lock->read_no_write_count)
- {
- found_errors++;
- fprintf(stderr,
- "Warning at '%s': Locks read_no_write_count was %u when it should have been %u\n", where, lock->read_no_write_count,count);
- }
-
- if (!lock->write.data)
- {
- if (!allow_no_locks && !lock->read.data &&
- (lock->write_wait.data || lock->read_wait.data))
- {
- found_errors++;
- fprintf(stderr,
- "Warning at '%s': No locks in use but locks are in wait queue\n",
- where);
- }
- if (!lock->write_wait.data)
- {
- if (!allow_no_locks && lock->read_wait.data)
- {
- found_errors++;
- fprintf(stderr,
- "Warning at '%s': No write locks and waiting read locks\n",
- where);
- }
- }
- else
- {
- if (!allow_no_locks &&
- (((lock->write_wait.data->type == TL_WRITE_CONCURRENT_INSERT ||
- lock->write_wait.data->type == TL_WRITE_ALLOW_WRITE) &&
- !lock->read_no_write_count) ||
- (lock->write_wait.data->type == TL_WRITE_DELAYED &&
- !lock->read.data)))
- {
- found_errors++;
- fprintf(stderr,
- "Warning at '%s': Write lock %d waiting while no exclusive read locks\n",where,(int) lock->write_wait.data->type);
- }
- }
- }
- else
- { /* Have write lock */
- if (lock->write_wait.data)
- {
- if (!allow_no_locks &&
- lock->write.data->type == TL_WRITE_ALLOW_WRITE &&
- lock->write_wait.data->type == TL_WRITE_ALLOW_WRITE)
- {
- found_errors++;
- fprintf(stderr,
- "Warning at '%s': Found WRITE_ALLOW_WRITE lock waiting for WRITE_ALLOW_WRITE lock\n",
- where);
- }
- }
- if (lock->read.data)
- {
- if (!thr_lock_owner_equal(lock->write.data->owner,
- lock->read.data->owner) &&
- ((lock->write.data->type > TL_WRITE_DELAYED &&
- lock->write.data->type != TL_WRITE_ONLY) ||
- ((lock->write.data->type == TL_WRITE_CONCURRENT_INSERT ||
- lock->write.data->type == TL_WRITE_ALLOW_WRITE) &&
- lock->read_no_write_count)))
- {
- found_errors++;
- fprintf(stderr,
- "Warning at '%s': Found lock of type %d that is write and read locked\n",
- where, lock->write.data->type);
- DBUG_PRINT("warning",("At '%s': Found lock of type %d that is write and read locked\n",
- where, lock->write.data->type));
-
- }
- }
- if (lock->read_wait.data)
- {
- if (!allow_no_locks && lock->write.data->type <= TL_WRITE_DELAYED &&
- lock->read_wait.data->type <= TL_READ_HIGH_PRIORITY)
- {
- found_errors++;
- fprintf(stderr,
- "Warning at '%s': Found read lock of type %d waiting for write lock of type %d\n",
- where,
- (int) lock->read_wait.data->type,
- (int) lock->write.data->type);
- }
- }
- }
- }
- if (found_errors != old_found_errors)
- {
- DBUG_PRINT("error",("Found wrong lock"));
- }
- }
- DBUG_VOID_RETURN;
-}
-
-#else /* EXTRA_DEBUG */
-#define check_locks(A,B,C)
-#endif
-
-
- /* Initialize a lock */
-
-void thr_lock_init(THR_LOCK *lock)
-{
- DBUG_ENTER("thr_lock_init");
- bzero((char*) lock,sizeof(*lock));
- mysql_mutex_init(key_THR_LOCK_mutex, &lock->mutex, MY_MUTEX_INIT_FAST);
- lock->read.last= &lock->read.data;
- lock->read_wait.last= &lock->read_wait.data;
- lock->write_wait.last= &lock->write_wait.data;
- lock->write.last= &lock->write.data;
-
- mysql_mutex_lock(&THR_LOCK_lock); /* Add to locks in use */
- lock->list.data=(void*) lock;
- thr_lock_thread_list=list_add(thr_lock_thread_list,&lock->list);
- mysql_mutex_unlock(&THR_LOCK_lock);
- DBUG_VOID_RETURN;
-}
-
-
-void thr_lock_delete(THR_LOCK *lock)
-{
- DBUG_ENTER("thr_lock_delete");
- mysql_mutex_lock(&THR_LOCK_lock);
- thr_lock_thread_list=list_delete(thr_lock_thread_list,&lock->list);
- mysql_mutex_unlock(&THR_LOCK_lock);
- mysql_mutex_destroy(&lock->mutex);
- DBUG_VOID_RETURN;
-}
-
-
-void thr_lock_info_init(THR_LOCK_INFO *info)
-{
- struct st_my_thread_var *tmp= my_thread_var;
- info->thread= tmp->pthread_self;
- info->thread_id= tmp->id;
-}
-
- /* Initialize a lock instance */
-
-void thr_lock_data_init(THR_LOCK *lock,THR_LOCK_DATA *data, void *param)
-{
- data->lock=lock;
- data->type=TL_UNLOCK;
- data->owner= 0; /* no owner yet */
- data->status_param=param;
- data->cond=0;
-}
-
-
-static inline my_bool
-has_old_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner)
-{
- for ( ; data ; data=data->next)
- {
- if (thr_lock_owner_equal(data->owner, owner))
- return 1; /* Already locked by thread */
- }
- return 0;
-}
-
-static inline my_bool have_specific_lock(THR_LOCK_DATA *data,
- enum thr_lock_type type)
-{
- for ( ; data ; data=data->next)
- {
- if (data->type == type)
- return 1;
- }
- return 0;
-}
-
-
-static void wake_up_waiters(THR_LOCK *lock);
-
-
-static enum enum_thr_lock_result
-wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
- my_bool in_wait_list, ulong lock_wait_timeout)
-{
- struct st_my_thread_var *thread_var= my_thread_var;
- mysql_cond_t *cond= &thread_var->suspend;
- struct timespec wait_timeout;
- enum enum_thr_lock_result result= THR_LOCK_ABORTED;
- const char *old_proc_info;
- DBUG_ENTER("wait_for_lock");
-
- /*
- One can use this to signal when a thread is going to wait for a lock.
- See debug_sync.cc.
-
- Beware of waiting for a signal here. The lock has aquired its mutex.
- While waiting on a signal here, the locking thread could not aquire
- the mutex to release the lock. One could lock up the table
- completely.
-
- In detail it works so: When thr_lock() tries to acquire a table
- lock, it locks the lock->mutex, checks if it can have the lock, and
- if not, it calls wait_for_lock(). Here it unlocks the table lock
- while waiting on a condition. The sync point is located before this
- wait for condition. If we have a waiting action here, we hold the
- the table locks mutex all the time. Any attempt to look at the table
- lock by another thread blocks it immediately on lock->mutex. This
- can easily become an unexpected and unobvious blockage. So be
- warned: Do not request a WAIT_FOR action for the 'wait_for_lock'
- sync point unless you really know what you do.
- */
- DEBUG_SYNC_C("wait_for_lock");
-
- if (!in_wait_list)
- {
- (*wait->last)=data; /* Wait for lock */
- data->prev= wait->last;
- wait->last= &data->next;
- }
-
- statistic_increment(locks_waited, &THR_LOCK_lock);
-
- /* Set up control struct to allow others to abort locks */
- thread_var->current_mutex= &data->lock->mutex;
- thread_var->current_cond= cond;
- data->cond= cond;
-
- old_proc_info= proc_info_hook(NULL, "Waiting for table level lock",
- __func__, __FILE__, __LINE__);
-
- /*
- Since before_lock_wait potentially can create more threads to
- scheduler work for, we don't want to call the before_lock_wait
- callback unless it will really start to wait.
-
- For similar reasons, we do not want to call before_lock_wait and
- after_lock_wait for each lap around the loop, so we restrict
- ourselves to call it before_lock_wait once before starting to wait
- and once after the thread has exited the wait loop.
- */
- if ((!thread_var->abort || in_wait_list) && before_lock_wait)
- (*before_lock_wait)();
-
- set_timespec(wait_timeout, lock_wait_timeout);
- while (!thread_var->abort || in_wait_list)
- {
- int rc= mysql_cond_timedwait(cond, &data->lock->mutex, &wait_timeout);
- /*
- We must break the wait if one of the following occurs:
- - the connection has been aborted (!thread_var->abort), but
- this is not a delayed insert thread (in_wait_list). For a delayed
- insert thread the proper action at shutdown is, apparently, to
- acquire the lock and complete the insert.
- - the lock has been granted (data->cond is set to NULL by the granter),
- or the waiting has been aborted (additionally data->type is set to
- TL_UNLOCK).
- - the wait has timed out (rc == ETIMEDOUT)
- Order of checks below is important to not report about timeout
- if the predicate is true.
- */
- if (data->cond == 0)
- {
- DBUG_PRINT("thr_lock", ("lock granted/aborted"));
- break;
- }
- if (rc == ETIMEDOUT || rc == ETIME)
- {
- /* purecov: begin inspected */
- DBUG_PRINT("thr_lock", ("lock timed out"));
- result= THR_LOCK_WAIT_TIMEOUT;
- break;
- /* purecov: end */
- }
- }
-
- /*
- We call the after_lock_wait callback once the wait loop has
- finished.
- */
- if (after_lock_wait)
- (*after_lock_wait)();
-
- DBUG_PRINT("thr_lock", ("aborted: %d in_wait_list: %d",
- thread_var->abort, in_wait_list));
-
- if (data->cond || data->type == TL_UNLOCK)
- {
- if (data->cond) /* aborted or timed out */
- {
- if (((*data->prev)=data->next)) /* remove from wait-list */
- data->next->prev= data->prev;
- else
- wait->last=data->prev;
- data->type= TL_UNLOCK; /* No lock */
- check_locks(data->lock, "killed or timed out wait_for_lock", 1);
- wake_up_waiters(data->lock);
- }
- else
- {
- DBUG_PRINT("thr_lock", ("lock aborted"));
- check_locks(data->lock, "aborted wait_for_lock", 0);
- }
- }
- else
- {
- result= THR_LOCK_SUCCESS;
- if (data->lock->get_status)
- (*data->lock->get_status)(data->status_param, 0);
- check_locks(data->lock,"got wait_for_lock",0);
- }
- mysql_mutex_unlock(&data->lock->mutex);
-
- /* The following must be done after unlock of lock->mutex */
- mysql_mutex_lock(&thread_var->mutex);
- thread_var->current_mutex= 0;
- thread_var->current_cond= 0;
- mysql_mutex_unlock(&thread_var->mutex);
-
- proc_info_hook(NULL, old_proc_info, __func__, __FILE__, __LINE__);
-
- DBUG_RETURN(result);
-}
-
-
-enum enum_thr_lock_result
-thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner,
- enum thr_lock_type lock_type, ulong lock_wait_timeout)
-{
- THR_LOCK *lock=data->lock;
- enum enum_thr_lock_result result= THR_LOCK_SUCCESS;
- struct st_lock_list *wait_queue;
- DBUG_ENTER("thr_lock");
-
- data->next=0;
- data->cond=0; /* safety */
- data->type=lock_type;
- data->owner= owner; /* Must be reset ! */
- mysql_mutex_lock(&lock->mutex);
- DBUG_PRINT("lock",("data: 0x%lx thread: 0x%lx lock: 0x%lx type: %d",
- (long) data, data->owner->thread_id,
- (long) lock, (int) lock_type));
- check_locks(lock,(uint) lock_type <= (uint) TL_READ_NO_INSERT ?
- "enter read_lock" : "enter write_lock",0);
- if ((int) lock_type <= (int) TL_READ_NO_INSERT)
- {
- /* Request for READ lock */
- if (lock->write.data)
- {
- /*
- We can allow a read lock even if there is already a
- write lock on the table if they are owned by the same
- thread or if they satisfy the following lock
- compatibility matrix:
-
- Request
- /-------
- H|++++ WRITE_ALLOW_WRITE
- e|+++- WRITE_CONCURRENT_INSERT
- l|++++ WRITE_DELAYED
- d ||||
- |||\= READ_NO_INSERT
- ||\ = READ_HIGH_PRIORITY
- |\ = READ_WITH_SHARED_LOCKS
- \ = READ
-
-
- + = Request can be satisified.
- - = Request cannot be satisified.
-
- READ_NO_INSERT and WRITE_ALLOW_WRITE should in principle
- be incompatible. However this will cause starvation of
- LOCK TABLE READ in InnoDB under high write load.
- See Bug#42147 for more information.
- */
-
- DBUG_PRINT("lock",("write locked 1 by thread: 0x%lx",
- lock->write.data->owner->thread_id));
- if (thr_lock_owner_equal(data->owner, lock->write.data->owner) ||
- (lock->write.data->type <= TL_WRITE_DELAYED &&
- (((int) lock_type <= (int) TL_READ_HIGH_PRIORITY) ||
- (lock->write.data->type != TL_WRITE_CONCURRENT_INSERT))))
- { /* Already got a write lock */
- (*lock->read.last)=data; /* Add to running FIFO */
- data->prev=lock->read.last;
- lock->read.last= &data->next;
- if (lock_type == TL_READ_NO_INSERT)
- lock->read_no_write_count++;
- check_locks(lock,"read lock with old write lock",0);
- if (lock->get_status)
- (*lock->get_status)(data->status_param, 0);
- statistic_increment(locks_immediate,&THR_LOCK_lock);
- goto end;
- }
- if (lock->write.data->type == TL_WRITE_ONLY)
- {
- /* We are not allowed to get a READ lock in this case */
- data->type=TL_UNLOCK;
- result= THR_LOCK_ABORTED; /* Can't wait for this one */
- goto end;
- }
- }
- else if (!lock->write_wait.data ||
- lock->write_wait.data->type <= TL_WRITE_LOW_PRIORITY ||
- lock_type == TL_READ_HIGH_PRIORITY ||
- has_old_lock(lock->read.data, data->owner)) /* Has old read lock */
- { /* No important write-locks */
- (*lock->read.last)=data; /* Add to running FIFO */
- data->prev=lock->read.last;
- lock->read.last= &data->next;
- if (lock->get_status)
- (*lock->get_status)(data->status_param, 0);
- if (lock_type == TL_READ_NO_INSERT)
- lock->read_no_write_count++;
- check_locks(lock,"read lock with no write locks",0);
- statistic_increment(locks_immediate,&THR_LOCK_lock);
- goto end;
- }
- /*
- We're here if there is an active write lock or no write
- lock but a high priority write waiting in the write_wait queue.
- In the latter case we should yield the lock to the writer.
- */
- wait_queue= &lock->read_wait;
- }
- else /* Request for WRITE lock */
- {
- if (lock_type == TL_WRITE_DELAYED)
- {
- if (lock->write.data && lock->write.data->type == TL_WRITE_ONLY)
- {
- data->type=TL_UNLOCK;
- result= THR_LOCK_ABORTED; /* Can't wait for this one */
- goto end;
- }
- if (lock->write.data || lock->read.data)
- {
- /* Add delayed write lock to write_wait queue, and return at once */
- (*lock->write_wait.last)=data;
- data->prev=lock->write_wait.last;
- lock->write_wait.last= &data->next;
- data->cond=get_cond();
- /*
- We don't have to do get_status here as we will do it when we change
- the delayed lock to a real write lock
- */
- statistic_increment(locks_immediate,&THR_LOCK_lock);
- goto end;
- }
- }
- else if (lock_type == TL_WRITE_CONCURRENT_INSERT && ! lock->check_status)
- data->type=lock_type= thr_upgraded_concurrent_insert_lock;
-
- if (lock->write.data) /* If there is a write lock */
- {
- if (lock->write.data->type == TL_WRITE_ONLY)
- {
- /* purecov: begin tested */
- /* Allow lock owner to bypass TL_WRITE_ONLY. */
- if (!thr_lock_owner_equal(data->owner, lock->write.data->owner))
- {
- /* We are not allowed to get a lock in this case */
- data->type=TL_UNLOCK;
- result= THR_LOCK_ABORTED; /* Can't wait for this one */
- goto end;
- }
- /* purecov: end */
- }
-
- /*
- The idea is to allow us to get a lock at once if we already have
- a write lock or if there is no pending write locks and if all
- write locks are of TL_WRITE_ALLOW_WRITE type.
-
- Note that, since lock requests for the same table are sorted in
- such way that requests with higher thr_lock_type value come first
- (with one exception (*)), lock being requested usually (**) has
- equal or "weaker" type than one which thread might have already
- acquired.
- *) The only exception to this rule is case when type of old lock
- is TL_WRITE_LOW_PRIORITY and type of new lock is changed inside
- of thr_lock() from TL_WRITE_CONCURRENT_INSERT to TL_WRITE since
- engine turns out to be not supporting concurrent inserts.
- Note that since TL_WRITE has the same compatibility rules as
- TL_WRITE_LOW_PRIORITY (their only difference is priority),
- it is OK to grant new lock without additional checks in such
- situation.
- **) The exceptions are situations when:
- - when old lock type is TL_WRITE_DELAYED
- But these should never happen within MySQL.
- Therefore it is OK to allow acquiring write lock on the table if
- this thread already holds some write lock on it.
-
- (INSERT INTO t1 VALUES (f1()), where f1() is stored function which
- tries to update t1, is an example of statement which requests two
- different types of write lock on the same table).
- */
- DBUG_ASSERT(! has_old_lock(lock->write.data, data->owner) ||
- ((lock_type <= lock->write.data->type ||
- (lock_type == TL_WRITE &&
- lock->write.data->type == TL_WRITE_LOW_PRIORITY)) &&
- lock->write.data->type != TL_WRITE_DELAYED));
-
- if ((lock_type == TL_WRITE_ALLOW_WRITE &&
- ! lock->write_wait.data &&
- lock->write.data->type == TL_WRITE_ALLOW_WRITE) ||
- has_old_lock(lock->write.data, data->owner))
- {
- /*
- We have already got a write lock or all locks are
- TL_WRITE_ALLOW_WRITE
- */
- DBUG_PRINT("info", ("write_wait.data: 0x%lx old_type: %d",
- (ulong) lock->write_wait.data,
- lock->write.data->type));
-
- (*lock->write.last)=data; /* Add to running fifo */
- data->prev=lock->write.last;
- lock->write.last= &data->next;
- check_locks(lock,"second write lock",0);
- if (data->lock->get_status)
- (*data->lock->get_status)(data->status_param, 0);
- statistic_increment(locks_immediate,&THR_LOCK_lock);
- goto end;
- }
- DBUG_PRINT("lock",("write locked 2 by thread: 0x%lx",
- lock->write.data->owner->thread_id));
- }
- else
- {
- DBUG_PRINT("info", ("write_wait.data: 0x%lx",
- (ulong) lock->write_wait.data));
- if (!lock->write_wait.data)
- { /* no scheduled write locks */
- my_bool concurrent_insert= 0;
- if (lock_type == TL_WRITE_CONCURRENT_INSERT)
- {
- concurrent_insert= 1;
- if ((*lock->check_status)(data->status_param))
- {
- concurrent_insert= 0;
- data->type=lock_type= thr_upgraded_concurrent_insert_lock;
- }
- }
-
- if (!lock->read.data ||
- (lock_type <= TL_WRITE_DELAYED &&
- ((lock_type != TL_WRITE_CONCURRENT_INSERT &&
- lock_type != TL_WRITE_ALLOW_WRITE) ||
- !lock->read_no_write_count)))
- {
- (*lock->write.last)=data; /* Add as current write lock */
- data->prev=lock->write.last;
- lock->write.last= &data->next;
- if (data->lock->get_status)
- (*data->lock->get_status)(data->status_param, concurrent_insert);
- check_locks(lock,"only write lock",0);
- statistic_increment(locks_immediate,&THR_LOCK_lock);
- goto end;
- }
- }
- DBUG_PRINT("lock",("write locked 3 by thread: 0x%lx type: %d",
- lock->read.data->owner->thread_id, data->type));
- }
- wait_queue= &lock->write_wait;
- }
- /* Can't get lock yet; Wait for it */
- DBUG_RETURN(wait_for_lock(wait_queue, data, 0, lock_wait_timeout));
-end:
- mysql_mutex_unlock(&lock->mutex);
- DBUG_RETURN(result);
-}
-
-
-static inline void free_all_read_locks(THR_LOCK *lock,
- my_bool using_concurrent_insert)
-{
- THR_LOCK_DATA *data=lock->read_wait.data;
-
- check_locks(lock,"before freeing read locks",1);
-
- /* move all locks from read_wait list to read list */
- (*lock->read.last)=data;
- data->prev=lock->read.last;
- lock->read.last=lock->read_wait.last;
-
- /* Clear read_wait list */
- lock->read_wait.last= &lock->read_wait.data;
-
- do
- {
- mysql_cond_t *cond= data->cond;
- if ((int) data->type == (int) TL_READ_NO_INSERT)
- {
- if (using_concurrent_insert)
- {
- /*
- We can't free this lock;
- Link lock away from read chain back into read_wait chain
- */
- if (((*data->prev)=data->next))
- data->next->prev=data->prev;
- else
- lock->read.last=data->prev;
- *lock->read_wait.last= data;
- data->prev= lock->read_wait.last;
- lock->read_wait.last= &data->next;
- continue;
- }
- lock->read_no_write_count++;
- }
- /* purecov: begin inspected */
- DBUG_PRINT("lock",("giving read lock to thread: 0x%lx",
- data->owner->thread_id));
- /* purecov: end */
- data->cond=0; /* Mark thread free */
- mysql_cond_signal(cond);
- } while ((data=data->next));
- *lock->read_wait.last=0;
- if (!lock->read_wait.data)
- lock->write_lock_count=0;
- check_locks(lock,"after giving read locks",0);
-}
-
- /* Unlock lock and free next thread on same lock */
-
-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: 0x%lx lock: 0x%lx",
- (long) data, data->owner->thread_id, (long) lock));
- mysql_mutex_lock(&lock->mutex);
- check_locks(lock,"start of release lock",0);
-
- if (((*data->prev)=data->next)) /* remove from lock-list */
- data->next->prev= data->prev;
- else if (lock_type <= TL_READ_NO_INSERT)
- lock->read.last=data->prev;
- else if (lock_type == TL_WRITE_DELAYED && data->cond)
- {
- /*
- This only happens in extreme circumstances when a
- write delayed lock that is waiting for a lock
- */
- lock->write_wait.last=data->prev; /* Put it on wait queue */
- }
- else
- lock->write.last=data->prev;
- if (lock_type >= TL_WRITE_CONCURRENT_INSERT)
- {
- if (lock->update_status)
- (*lock->update_status)(data->status_param);
- }
- else
- {
- if (lock->restore_status)
- (*lock->restore_status)(data->status_param);
- }
- if (lock_type == TL_READ_NO_INSERT)
- lock->read_no_write_count--;
- data->type=TL_UNLOCK; /* Mark unlocked */
- check_locks(lock,"after releasing lock",1);
- wake_up_waiters(lock);
- mysql_mutex_unlock(&lock->mutex);
- DBUG_VOID_RETURN;
-}
-
-
-/**
- @brief Wake up all threads which pending requests for the lock
- can be satisfied.
-
- @param lock Lock for which threads should be woken up
-
-*/
-
-static void wake_up_waiters(THR_LOCK *lock)
-{
- THR_LOCK_DATA *data;
- enum thr_lock_type lock_type;
-
- DBUG_ENTER("wake_up_waiters");
-
- if (!lock->write.data) /* If no active write locks */
- {
- data=lock->write_wait.data;
- if (!lock->read.data) /* If no more locks in use */
- {
- /* Release write-locks with TL_WRITE or TL_WRITE_ONLY priority first */
- if (data &&
- (data->type != TL_WRITE_LOW_PRIORITY || !lock->read_wait.data ||
- lock->read_wait.data->type < TL_READ_HIGH_PRIORITY))
- {
- if (lock->write_lock_count++ > max_write_lock_count)
- {
- /* Too many write locks in a row; Release all waiting read locks */
- lock->write_lock_count=0;
- if (lock->read_wait.data)
- {
- DBUG_PRINT("info",("Freeing all read_locks because of max_write_lock_count"));
- free_all_read_locks(lock,0);
- goto end;
- }
- }
- for (;;)
- {
- if (((*data->prev)=data->next)) /* remove from wait-list */
- data->next->prev= data->prev;
- else
- lock->write_wait.last=data->prev;
- (*lock->write.last)=data; /* Put in execute list */
- data->prev=lock->write.last;
- data->next=0;
- lock->write.last= &data->next;
- if (data->type == TL_WRITE_CONCURRENT_INSERT &&
- (*lock->check_status)(data->status_param))
- data->type=TL_WRITE; /* Upgrade lock */
- /* purecov: begin inspected */
- DBUG_PRINT("lock",("giving write lock of type %d to thread: 0x%lx",
- data->type, data->owner->thread_id));
- /* purecov: end */
- {
- mysql_cond_t *cond= data->cond;
- data->cond=0; /* Mark thread free */
- mysql_cond_signal(cond); /* Start waiting thread */
- }
- if (data->type != TL_WRITE_ALLOW_WRITE ||
- !lock->write_wait.data ||
- lock->write_wait.data->type != TL_WRITE_ALLOW_WRITE)
- break;
- data=lock->write_wait.data; /* Free this too */
- }
- if (data->type >= TL_WRITE_LOW_PRIORITY)
- goto end;
- /* Release possible read locks together with the write lock */
- }
- if (lock->read_wait.data)
- free_all_read_locks(lock,
- data &&
- (data->type == TL_WRITE_CONCURRENT_INSERT ||
- data->type == TL_WRITE_ALLOW_WRITE));
- else
- {
- DBUG_PRINT("lock",("No waiting read locks to free"));
- }
- }
- else if (data &&
- (lock_type=data->type) <= TL_WRITE_DELAYED &&
- ((lock_type != TL_WRITE_CONCURRENT_INSERT &&
- lock_type != TL_WRITE_ALLOW_WRITE) ||
- !lock->read_no_write_count))
- {
- /*
- For DELAYED, ALLOW_READ, WRITE_ALLOW_WRITE or CONCURRENT_INSERT locks
- start WRITE locks together with the READ locks
- */
- if (lock_type == TL_WRITE_CONCURRENT_INSERT &&
- (*lock->check_status)(data->status_param))
- {
- data->type=TL_WRITE; /* Upgrade lock */
- if (lock->read_wait.data)
- free_all_read_locks(lock,0);
- goto end;
- }
- do {
- mysql_cond_t *cond= data->cond;
- if (((*data->prev)=data->next)) /* remove from wait-list */
- data->next->prev= data->prev;
- else
- lock->write_wait.last=data->prev;
- (*lock->write.last)=data; /* Put in execute list */
- data->prev=lock->write.last;
- lock->write.last= &data->next;
- data->next=0; /* Only one write lock */
- data->cond=0; /* Mark thread free */
- mysql_cond_signal(cond); /* Start waiting thread */
- } while (lock_type == TL_WRITE_ALLOW_WRITE &&
- (data=lock->write_wait.data) &&
- data->type == TL_WRITE_ALLOW_WRITE);
- if (lock->read_wait.data)
- free_all_read_locks(lock,
- (lock_type == TL_WRITE_CONCURRENT_INSERT ||
- lock_type == TL_WRITE_ALLOW_WRITE));
- }
- else if (!data && lock->read_wait.data)
- free_all_read_locks(lock,0);
- }
-end:
- check_locks(lock, "after waking up waiters", 0);
- DBUG_VOID_RETURN;
-}
-
-
-/*
-** Get all locks in a specific order to avoid dead-locks
-** Sort acording to lock position and put write_locks before read_locks if
-** lock on same lock.
-*/
-
-
-#define LOCK_CMP(A,B) ((uchar*) (A->lock) - (uint) ((A)->type) < (uchar*) (B->lock)- (uint) ((B)->type))
-
-static void sort_locks(THR_LOCK_DATA **data,uint count)
-{
- THR_LOCK_DATA **pos,**end,**prev,*tmp;
-
- /* Sort locks with insertion sort (fast because almost always few locks) */
-
- for (pos=data+1,end=data+count; pos < end ; pos++)
- {
- tmp= *pos;
- if (LOCK_CMP(tmp,pos[-1]))
- {
- prev=pos;
- do {
- prev[0]=prev[-1];
- } while (--prev != data && LOCK_CMP(tmp,prev[-1]));
- prev[0]=tmp;
- }
- }
-}
-
-
-enum enum_thr_lock_result
-thr_multi_lock(THR_LOCK_DATA **data, uint count, THR_LOCK_INFO *owner,
- ulong lock_wait_timeout)
-{
- THR_LOCK_DATA **pos,**end;
- DBUG_ENTER("thr_multi_lock");
- DBUG_PRINT("lock",("data: 0x%lx count: %d", (long) data, count));
- if (count > 1)
- sort_locks(data,count);
- /* lock everything */
- for (pos=data,end=data+count; pos < end ; pos++)
- {
- enum enum_thr_lock_result result= thr_lock(*pos, owner, (*pos)->type,
- lock_wait_timeout);
- if (result != THR_LOCK_SUCCESS)
- { /* Aborted */
- thr_multi_unlock(data,(uint) (pos-data));
- DBUG_RETURN(result);
- }
- DEBUG_SYNC_C("thr_multi_lock_after_thr_lock");
-#ifdef MAIN
- printf("Thread: %s Got lock: 0x%lx type: %d\n",my_thread_name(),
- (long) pos[0]->lock, pos[0]->type); fflush(stdout);
-#endif
- }
- thr_lock_merge_status(data, count);
- DBUG_RETURN(THR_LOCK_SUCCESS);
-}
-
-
-/**
- Ensure that all locks for a given table have the same
- status_param.
-
- This is a MyISAM and possibly Maria specific crutch. MyISAM
- engine stores data file length, record count and other table
- properties in status_param member of handler. When a table is
- locked, connection-local copy is made from a global copy
- (myisam_share) by mi_get_status(). When a table is unlocked,
- the changed status is transferred back to the global share by
- mi_update_status().
-
- One thing MyISAM doesn't do is to ensure that when the same
- table is opened twice in a connection all instances share the
- same status_param. This is necessary, however: for one, to keep
- all instances of a connection "on the same page" with regard to
- the current state of the table. For other, unless this is done,
- myisam_share will always get updated from the last unlocked
- instance (in mi_update_status()), and when this instance was not
- the one that was used to update data, records may be lost.
-
- For each table, this function looks up the last lock_data in the
- list of acquired locks, and makes sure that all other instances
- share status_param with it.
-*/
-
-void
-thr_lock_merge_status(THR_LOCK_DATA **data, uint count)
-{
-#if !defined(DONT_USE_RW_LOCKS)
- THR_LOCK_DATA **pos= data;
- THR_LOCK_DATA **end= data + count;
- if (count > 1)
- {
- THR_LOCK_DATA *last_lock= end[-1];
- pos=end-1;
- do
- {
- pos--;
- if (last_lock->lock == (*pos)->lock &&
- last_lock->lock->copy_status)
- {
- if (last_lock->type <= TL_READ_NO_INSERT)
- {
- THR_LOCK_DATA **read_lock;
- /*
- If we are locking the same table with read locks we must ensure
- that all tables share the status of the last write lock or
- the same read lock.
- */
- for (;
- (*pos)->type <= TL_READ_NO_INSERT &&
- pos != data &&
- pos[-1]->lock == (*pos)->lock ;
- pos--) ;
-
- read_lock = pos+1;
- do
- {
- (last_lock->lock->copy_status)((*read_lock)->status_param,
- (*pos)->status_param);
- } while (*(read_lock++) != last_lock);
- last_lock= (*pos); /* Point at last write lock */
- }
- else
- (*last_lock->lock->copy_status)((*pos)->status_param,
- last_lock->status_param);
- }
- else
- last_lock=(*pos);
- } while (pos != data);
- }
-#endif
-}
-
- /* free all locks */
-
-void thr_multi_unlock(THR_LOCK_DATA **data,uint count)
-{
- THR_LOCK_DATA **pos,**end;
- DBUG_ENTER("thr_multi_unlock");
- DBUG_PRINT("lock",("data: 0x%lx count: %d", (long) data, count));
-
- for (pos=data,end=data+count; pos < end ; pos++)
- {
-#ifdef MAIN
- printf("Thread: %s Rel lock: 0x%lx type: %d\n",
- my_thread_name(), (long) pos[0]->lock, pos[0]->type);
- fflush(stdout);
-#endif
- if ((*pos)->type != TL_UNLOCK)
- thr_unlock(*pos);
- else
- {
- DBUG_PRINT("lock",("Free lock: data: 0x%lx thread: 0x%lx lock: 0x%lx",
- (long) *pos, (*pos)->owner->thread_id,
- (long) (*pos)->lock));
- }
- }
- DBUG_VOID_RETURN;
-}
-
-/*
- Abort all threads waiting for a lock. The lock will be upgraded to
- TL_WRITE_ONLY to abort any new accesses to the lock
-*/
-
-void thr_abort_locks(THR_LOCK *lock, my_bool upgrade_lock)
-{
- THR_LOCK_DATA *data;
- DBUG_ENTER("thr_abort_locks");
- mysql_mutex_lock(&lock->mutex);
-
- for (data=lock->read_wait.data; data ; data=data->next)
- {
- data->type=TL_UNLOCK; /* Mark killed */
- /* It's safe to signal the cond first: we're still holding the mutex. */
- mysql_cond_signal(data->cond);
- data->cond=0; /* Removed from list */
- }
- for (data=lock->write_wait.data; data ; data=data->next)
- {
- data->type=TL_UNLOCK;
- mysql_cond_signal(data->cond);
- data->cond=0;
- }
- 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 (upgrade_lock && lock->write.data)
- lock->write.data->type=TL_WRITE_ONLY;
- mysql_mutex_unlock(&lock->mutex);
- DBUG_VOID_RETURN;
-}
-
-
-/*
- Abort all locks for specific table/thread combination
-
- This is used to abort all locks for a specific thread
-*/
-
-my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread_id)
-{
- THR_LOCK_DATA *data;
- my_bool found= FALSE;
- DBUG_ENTER("thr_abort_locks_for_thread");
-
- mysql_mutex_lock(&lock->mutex);
- for (data= lock->read_wait.data; data ; data= data->next)
- {
- if (data->owner->thread_id == thread_id) /* purecov: tested */
- {
- DBUG_PRINT("info",("Aborting read-wait lock"));
- data->type= TL_UNLOCK; /* Mark killed */
- /* It's safe to signal the cond first: we're still holding the mutex. */
- found= TRUE;
- mysql_cond_signal(data->cond);
- data->cond= 0; /* Removed from list */
-
- if (((*data->prev)= data->next))
- data->next->prev= data->prev;
- else
- lock->read_wait.last= data->prev;
- }
- }
- for (data= lock->write_wait.data; data ; data= data->next)
- {
- if (data->owner->thread_id == thread_id) /* purecov: tested */
- {
- DBUG_PRINT("info",("Aborting write-wait lock"));
- data->type= TL_UNLOCK;
- found= TRUE;
- mysql_cond_signal(data->cond);
- data->cond= 0;
-
- if (((*data->prev)= data->next))
- data->next->prev= data->prev;
- else
- lock->write_wait.last= data->prev;
- }
- }
- wake_up_waiters(lock);
- mysql_mutex_unlock(&lock->mutex);
- DBUG_RETURN(found);
-}
-
-
-/*
- 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. The normal downgrade variants are:
- 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;
-#ifndef DBUG_OFF
- enum thr_lock_type old_lock_type= in_data->type;
-#endif
- DBUG_ENTER("thr_downgrade_write_only_lock");
-
- mysql_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);
-
- mysql_mutex_unlock(&lock->mutex);
- DBUG_VOID_RETURN;
-}
-
-/* Upgrade a WRITE_DELAY lock to a WRITE_LOCK */
-
-my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data,
- enum thr_lock_type new_lock_type,
- ulong lock_wait_timeout)
-{
- THR_LOCK *lock=data->lock;
- DBUG_ENTER("thr_upgrade_write_delay_lock");
-
- mysql_mutex_lock(&lock->mutex);
- if (data->type == TL_UNLOCK || data->type >= TL_WRITE_LOW_PRIORITY)
- {
- mysql_mutex_unlock(&lock->mutex);
- DBUG_RETURN(data->type == TL_UNLOCK); /* Test if Aborted */
- }
- check_locks(lock,"before upgrading lock",0);
- /* TODO: Upgrade to TL_WRITE_CONCURRENT_INSERT in some cases */
- data->type= new_lock_type; /* Upgrade lock */
-
- /* Check if someone has given us the lock */
- if (!data->cond)
- {
- if (!lock->read.data) /* No read locks */
- { /* We have the lock */
- if (data->lock->get_status)
- (*data->lock->get_status)(data->status_param, 0);
- mysql_mutex_unlock(&lock->mutex);
- DBUG_RETURN(0);
- }
-
- if (((*data->prev)=data->next)) /* remove from lock-list */
- data->next->prev= data->prev;
- else
- lock->write.last=data->prev;
-
- if ((data->next=lock->write_wait.data)) /* Put first in lock_list */
- data->next->prev= &data->next;
- else
- lock->write_wait.last= &data->next;
- data->prev= &lock->write_wait.data;
- lock->write_wait.data=data;
- check_locks(lock,"upgrading lock",0);
- }
- else
- {
- check_locks(lock,"waiting for lock",0);
- }
- DBUG_RETURN(wait_for_lock(&lock->write_wait,data,1, lock_wait_timeout));
-}
-
-
-/* downgrade a WRITE lock to a WRITE_DELAY lock if there is pending locks */
-
-my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data,
- ulong lock_wait_timeout)
-{
- THR_LOCK *lock=data->lock;
- enum thr_lock_type write_lock_type;
- DBUG_ENTER("thr_reschedule_write_lock");
-
- mysql_mutex_lock(&lock->mutex);
- if (!lock->read_wait.data) /* No waiting read locks */
- {
- mysql_mutex_unlock(&lock->mutex);
- DBUG_RETURN(0);
- }
-
- write_lock_type= data->type;
- data->type=TL_WRITE_DELAYED;
- if (lock->update_status)
- (*lock->update_status)(data->status_param);
- if (((*data->prev)=data->next)) /* remove from lock-list */
- data->next->prev= data->prev;
- else
- lock->write.last=data->prev;
-
- if ((data->next=lock->write_wait.data)) /* Put first in lock_list */
- data->next->prev= &data->next;
- else
- lock->write_wait.last= &data->next;
- data->prev= &lock->write_wait.data;
- data->cond=get_cond(); /* This was zero */
- lock->write_wait.data=data;
- free_all_read_locks(lock,0);
-
- mysql_mutex_unlock(&lock->mutex);
- DBUG_RETURN(thr_upgrade_write_delay_lock(data, write_lock_type,
- lock_wait_timeout));
-}
-
-
-#include <my_sys.h>
-
-static void thr_print_lock(const char* name,struct st_lock_list *list)
-{
- THR_LOCK_DATA *data,**prev;
- uint count=0;
-
- if (list->data)
- {
- printf("%-10s: ",name);
- prev= &list->data;
- for (data=list->data; data && count++ < MAX_LOCKS ; data=data->next)
- {
- printf("0x%lx (%lu:%d); ", (ulong) data, data->owner->thread_id,
- (int) data->type);
- if (data->prev != prev)
- printf("\nWarning: prev didn't point at previous lock\n");
- prev= &data->next;
- }
- puts("");
- if (prev != list->last)
- printf("Warning: last didn't point at last lock\n");
- }
-}
-
-void thr_print_locks(void)
-{
- LIST *list;
- uint count=0;
-
- mysql_mutex_lock(&THR_LOCK_lock);
- puts("Current locks:");
- for (list= thr_lock_thread_list; list && count++ < MAX_THREADS;
- list= list_rest(list))
- {
- THR_LOCK *lock=(THR_LOCK*) list->data;
- mysql_mutex_lock(&lock->mutex);
- printf("lock: 0x%lx:",(ulong) lock);
- if ((lock->write_wait.data || lock->read_wait.data) &&
- (! lock->read.data && ! lock->write.data))
- printf(" WARNING: ");
- if (lock->write.data)
- printf(" write");
- if (lock->write_wait.data)
- printf(" write_wait");
- if (lock->read.data)
- printf(" read");
- if (lock->read_wait.data)
- printf(" read_wait");
- puts("");
- thr_print_lock("write",&lock->write);
- thr_print_lock("write_wait",&lock->write_wait);
- thr_print_lock("read",&lock->read);
- thr_print_lock("read_wait",&lock->read_wait);
- mysql_mutex_unlock(&lock->mutex);
- puts("");
- }
- fflush(stdout);
- mysql_mutex_unlock(&THR_LOCK_lock);
-}
-
-
-/*****************************************************************************
-** Test of thread locks
-****************************************************************************/
-
-#ifdef MAIN
-
-struct st_test {
- uint lock_nr;
- enum thr_lock_type lock_type;
-};
-
-THR_LOCK locks[5]; /* 4 locks */
-
-struct st_test test_0[] = {{0,TL_READ}}; /* One lock */
-struct st_test test_1[] = {{0,TL_READ},{0,TL_WRITE}}; /* Read and write lock of lock 0 */
-struct st_test test_2[] = {{1,TL_WRITE},{0,TL_READ},{2,TL_READ}};
-struct st_test test_3[] = {{2,TL_WRITE},{1,TL_READ},{0,TL_READ}}; /* Deadlock with test_2 ? */
-struct st_test test_4[] = {{0,TL_WRITE},{0,TL_READ},{0,TL_WRITE},{0,TL_READ}};
-struct st_test test_5[] = {{0,TL_READ},{1,TL_READ},{2,TL_READ},{3,TL_READ}}; /* Many reads */
-struct st_test test_6[] = {{0,TL_WRITE},{1,TL_WRITE},{2,TL_WRITE},{3,TL_WRITE}}; /* Many writes */
-struct st_test test_7[] = {{3,TL_READ}};
-struct st_test test_8[] = {{1,TL_READ_NO_INSERT},{2,TL_READ_NO_INSERT},{3,TL_READ_NO_INSERT}}; /* Should be quick */
-struct st_test test_9[] = {{4,TL_READ_HIGH_PRIORITY}};
-struct st_test test_10[] ={{4,TL_WRITE}};
-struct st_test test_11[] = {{0,TL_WRITE_LOW_PRIORITY},{1,TL_WRITE_LOW_PRIORITY},{2,TL_WRITE_LOW_PRIORITY},{3,TL_WRITE_LOW_PRIORITY}}; /* Many writes */
-struct st_test test_12[] = {{0,TL_WRITE_CONCURRENT_INSERT},{1,TL_WRITE_CONCURRENT_INSERT},{2,TL_WRITE_CONCURRENT_INSERT},{3,TL_WRITE_CONCURRENT_INSERT}};
-struct st_test test_13[] = {{0,TL_WRITE_CONCURRENT_INSERT},{1,TL_READ}};
-struct st_test test_14[] = {{0,TL_WRITE_ALLOW_WRITE},{1,TL_READ}};
-struct st_test test_15[] = {{0,TL_WRITE_ALLOW_WRITE},{1,TL_WRITE_ALLOW_WRITE}};
-
-struct st_test *tests[] = {test_0,test_1,test_2,test_3,test_4,test_5,test_6,
- test_7,test_8,test_9,test_10,test_11,test_12,
- test_13,test_14,test_15};
-int lock_counts[]= {sizeof(test_0)/sizeof(struct st_test),
- sizeof(test_1)/sizeof(struct st_test),
- sizeof(test_2)/sizeof(struct st_test),
- sizeof(test_3)/sizeof(struct st_test),
- sizeof(test_4)/sizeof(struct st_test),
- sizeof(test_5)/sizeof(struct st_test),
- sizeof(test_6)/sizeof(struct st_test),
- sizeof(test_7)/sizeof(struct st_test),
- sizeof(test_8)/sizeof(struct st_test),
- sizeof(test_9)/sizeof(struct st_test),
- sizeof(test_10)/sizeof(struct st_test),
- sizeof(test_11)/sizeof(struct st_test),
- sizeof(test_12)/sizeof(struct st_test),
- sizeof(test_13)/sizeof(struct st_test),
- sizeof(test_14)/sizeof(struct st_test),
- sizeof(test_15)/sizeof(struct st_test)
-};
-
-
-static mysql_cond_t COND_thread_count;
-static mysql_mutex_t LOCK_thread_count;
-static uint thread_count;
-static ulong sum=0;
-
-#define MAX_LOCK_COUNT 8
-#define TEST_TIMEOUT 100000
-
-/* The following functions is for WRITE_CONCURRENT_INSERT */
-
-static void test_get_status(void* param __attribute__((unused)),
- int concurrent_insert __attribute__((unused)))
-{
-}
-
-static void test_update_status(void* param __attribute__((unused)))
-{
-}
-
-static void test_copy_status(void* to __attribute__((unused)) ,
- void *from __attribute__((unused)))
-{
-}
-
-static my_bool test_check_status(void* param __attribute__((unused)))
-{
- return 0;
-}
-
-
-static void *test_thread(void *arg)
-{
- int i,j,param=*((int*) arg);
- THR_LOCK_DATA data[MAX_LOCK_COUNT];
- THR_LOCK_INFO lock_info;
- THR_LOCK_DATA *multi_locks[MAX_LOCK_COUNT];
- my_thread_init();
-
- printf("Thread %s (%d) started\n",my_thread_name(),param); fflush(stdout);
-
-
- thr_lock_info_init(&lock_info);
- for (i=0; i < lock_counts[param] ; i++)
- thr_lock_data_init(locks+tests[param][i].lock_nr,data+i,NULL);
- for (j=1 ; j < 10 ; j++) /* try locking 10 times */
- {
- for (i=0; i < lock_counts[param] ; i++)
- { /* Init multi locks */
- multi_locks[i]= &data[i];
- data[i].type= tests[param][i].lock_type;
- }
- thr_multi_lock(multi_locks, lock_counts[param], &lock_info, TEST_TIMEOUT);
- mysql_mutex_lock(&LOCK_thread_count);
- {
- int tmp=rand() & 7; /* Do something from 0-2 sec */
- if (tmp == 0)
- sleep(1);
- else if (tmp == 1)
- sleep(2);
- else
- {
- ulong k;
- for (k=0 ; k < (ulong) (tmp-2)*100000L ; k++)
- sum+=k;
- }
- }
- mysql_mutex_unlock(&LOCK_thread_count);
- thr_multi_unlock(multi_locks,lock_counts[param]);
- }
-
- printf("Thread %s (%d) ended\n",my_thread_name(),param); fflush(stdout);
- thr_print_locks();
- mysql_mutex_lock(&LOCK_thread_count);
- thread_count--;
- mysql_cond_signal(&COND_thread_count); /* Tell main we are ready */
- mysql_mutex_unlock(&LOCK_thread_count);
- free((uchar*) arg);
- return 0;
-}
-
-
-int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
-{
- pthread_t tid;
- pthread_attr_t thr_attr;
- int i,*param,error;
- MY_INIT(argv[0]);
- if (argc > 1 && argv[1][0] == '-' && argv[1][1] == '#')
- DBUG_PUSH(argv[1]+2);
-
- printf("Main thread: %s\n",my_thread_name());
-
- if ((error= mysql_cond_init(0, &COND_thread_count, NULL)))
- {
- fprintf(stderr, "Got error: %d from mysql_cond_init (errno: %d)",
- error,errno);
- exit(1);
- }
- if ((error= mysql_mutex_init(0, &LOCK_thread_count, MY_MUTEX_INIT_FAST)))
- {
- fprintf(stderr, "Got error: %d from mysql_cond_init (errno: %d)",
- error,errno);
- exit(1);
- }
-
- for (i=0 ; i < (int) array_elements(locks) ; i++)
- {
- thr_lock_init(locks+i);
- locks[i].check_status= test_check_status;
- locks[i].update_status=test_update_status;
- locks[i].copy_status= test_copy_status;
- locks[i].get_status= test_get_status;
- }
- if ((error=pthread_attr_init(&thr_attr)))
- {
- fprintf(stderr,"Got error: %d from pthread_attr_init (errno: %d)",
- error,errno);
- exit(1);
- }
- if ((error=pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED)))
- {
- fprintf(stderr,
- "Got error: %d from pthread_attr_setdetachstate (errno: %d)",
- error,errno);
- exit(1);
- }
-#ifndef pthread_attr_setstacksize /* void return value */
- if ((error=pthread_attr_setstacksize(&thr_attr,65536L)))
- {
- fprintf(stderr,"Got error: %d from pthread_attr_setstacksize (errno: %d)",
- error,errno);
- exit(1);
- }
-#endif
-#ifdef HAVE_THR_SETCONCURRENCY
- (void) thr_setconcurrency(2);
-#endif
- for (i=0 ; i < (int) array_elements(lock_counts) ; i++)
- {
- param=(int*) malloc(sizeof(int));
- *param=i;
-
- if ((error= mysql_mutex_lock(&LOCK_thread_count)))
- {
- fprintf(stderr, "Got error: %d from mysql_mutex_lock (errno: %d)",
- error, errno);
- exit(1);
- }
- if ((error= mysql_thread_create(0,
- &tid, &thr_attr, test_thread,
- (void*) param)))
- {
- fprintf(stderr, "Got error: %d from mysql_thread_create (errno: %d)\n",
- error, errno);
- mysql_mutex_unlock(&LOCK_thread_count);
- exit(1);
- }
- thread_count++;
- mysql_mutex_unlock(&LOCK_thread_count);
- }
-
- pthread_attr_destroy(&thr_attr);
- if ((error= mysql_mutex_lock(&LOCK_thread_count)))
- fprintf(stderr, "Got error: %d from mysql_mutex_lock\n", error);
- while (thread_count)
- {
- if ((error= mysql_cond_wait(&COND_thread_count, &LOCK_thread_count)))
- fprintf(stderr, "Got error: %d from mysql_cond_wait\n", error);
- }
- if ((error= mysql_mutex_unlock(&LOCK_thread_count)))
- fprintf(stderr, "Got error: %d from mysql_mutex_unlock\n", error);
- for (i=0 ; i < (int) array_elements(locks) ; i++)
- thr_lock_delete(locks+i);
-#ifdef EXTRA_DEBUG
- if (found_errors)
- printf("Got %d warnings\n",found_errors);
- else
-#endif
- printf("Test succeeded\n");
- return 0;
-}
-
-#endif /* MAIN */
diff --git a/dep/mysqllite/mysys/thr_mutex.c b/dep/mysqllite/mysys/thr_mutex.c
deleted file mode 100644
index 37ced4f7633..00000000000
--- a/dep/mysqllite/mysys/thr_mutex.c
+++ /dev/null
@@ -1,503 +0,0 @@
-/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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 */
-
-/* This makes a wrapper for mutex handling to make it easier to debug mutex */
-
-#include <my_global.h>
-#if defined(TARGET_OS_LINUX) && !defined (__USE_UNIX98)
-#define __USE_UNIX98 /* To get rw locks under Linux */
-#endif
-#if defined(SAFE_MUTEX)
-#undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */
-#include "mysys_priv.h"
-#include "my_static.h"
-#include <m_string.h>
-
-#ifndef DO_NOT_REMOVE_THREAD_WRAPPERS
-/* Remove wrappers */
-#undef pthread_mutex_t
-#undef pthread_mutex_init
-#undef pthread_mutex_lock
-#undef pthread_mutex_unlock
-#undef pthread_mutex_destroy
-#undef pthread_cond_wait
-#undef pthread_cond_timedwait
-#ifdef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT
-#define pthread_mutex_init(a,b) my_pthread_mutex_init((a),(b))
-#endif
-#endif /* DO_NOT_REMOVE_THREAD_WRAPPERS */
-
-/* Not instrumented */
-static pthread_mutex_t THR_LOCK_mutex;
-static ulong safe_mutex_count= 0; /* Number of mutexes created */
-#ifdef SAFE_MUTEX_DETECT_DESTROY
-static struct st_safe_mutex_info_t *safe_mutex_root= NULL;
-#endif
-
-void safe_mutex_global_init(void)
-{
- pthread_mutex_init(&THR_LOCK_mutex,MY_MUTEX_INIT_FAST);
-}
-
-
-int safe_mutex_init(safe_mutex_t *mp,
- const pthread_mutexattr_t *attr __attribute__((unused)),
- const char *file,
- uint line)
-{
- bzero((char*) mp,sizeof(*mp));
- pthread_mutex_init(&mp->global,MY_MUTEX_INIT_ERRCHK);
- pthread_mutex_init(&mp->mutex,attr);
- /* Mark that mutex is initialized */
- mp->file= file;
- mp->line= line;
-
-#ifdef SAFE_MUTEX_DETECT_DESTROY
- /*
- Monitor the freeing of mutexes. This code depends on single thread init
- and destroy
- */
- if ((mp->info= (safe_mutex_info_t *) malloc(sizeof(safe_mutex_info_t))))
- {
- struct st_safe_mutex_info_t *info =mp->info;
-
- info->init_file= file;
- info->init_line= line;
- info->prev= NULL;
- info->next= NULL;
-
- pthread_mutex_lock(&THR_LOCK_mutex);
- if ((info->next= safe_mutex_root))
- safe_mutex_root->prev= info;
- safe_mutex_root= info;
- safe_mutex_count++;
- pthread_mutex_unlock(&THR_LOCK_mutex);
- }
-#else
- pthread_mutex_lock(&THR_LOCK_mutex);
- safe_mutex_count++;
- pthread_mutex_unlock(&THR_LOCK_mutex);
-#endif /* SAFE_MUTEX_DETECT_DESTROY */
- return 0;
-}
-
-
-int safe_mutex_lock(safe_mutex_t *mp, my_bool try_lock, const char *file, uint line)
-{
- int error;
- if (!mp->file)
- {
- fprintf(stderr,
- "safe_mutex: Trying to lock unitialized mutex at %s, line %d\n",
- file, line);
- fflush(stderr);
- abort();
- }
-
- pthread_mutex_lock(&mp->global);
- if (mp->count > 0)
- {
- if (try_lock)
- {
- pthread_mutex_unlock(&mp->global);
- return EBUSY;
- }
- else if (pthread_equal(pthread_self(),mp->thread))
- {
- fprintf(stderr,
- "safe_mutex: Trying to lock mutex at %s, line %d, when the"
- " mutex was already locked at %s, line %d in thread %s\n",
- file,line,mp->file, mp->line, my_thread_name());
- fflush(stderr);
- abort();
- }
- }
- pthread_mutex_unlock(&mp->global);
-
- /*
- If we are imitating trylock(), we need to take special
- precautions.
-
- - We cannot use pthread_mutex_lock() only since another thread can
- overtake this thread and take the lock before this thread
- causing pthread_mutex_trylock() to hang. In this case, we should
- just return EBUSY. Hence, we use pthread_mutex_trylock() to be
- able to return immediately.
-
- - We cannot just use trylock() and continue execution below, since
- this would generate an error and abort execution if the thread
- was overtaken and trylock() returned EBUSY . In this case, we
- instead just return EBUSY, since this is the expected behaviour
- of trylock().
- */
- if (try_lock)
- {
- error= pthread_mutex_trylock(&mp->mutex);
- if (error == EBUSY)
- return error;
- }
- else
- error= pthread_mutex_lock(&mp->mutex);
-
- if (error || (error=pthread_mutex_lock(&mp->global)))
- {
- fprintf(stderr,"Got error %d when trying to lock mutex at %s, line %d\n",
- error, file, line);
- fflush(stderr);
- abort();
- }
- mp->thread= pthread_self();
- if (mp->count++)
- {
- fprintf(stderr,"safe_mutex: Error in thread libray: Got mutex at %s, \
-line %d more than 1 time\n", file,line);
- fflush(stderr);
- abort();
- }
- mp->file= file;
- mp->line=line;
- pthread_mutex_unlock(&mp->global);
- return error;
-}
-
-
-int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line)
-{
- int error;
- pthread_mutex_lock(&mp->global);
- if (mp->count == 0)
- {
- fprintf(stderr,"safe_mutex: Trying to unlock mutex that wasn't locked at %s, line %d\n Last used at %s, line: %d\n",
- file,line,mp->file ? mp->file : "",mp->line);
- fflush(stderr);
- abort();
- }
- if (!pthread_equal(pthread_self(),mp->thread))
- {
- fprintf(stderr,"safe_mutex: Trying to unlock mutex at %s, line %d that was locked by another thread at: %s, line: %d\n",
- file,line,mp->file,mp->line);
- fflush(stderr);
- abort();
- }
- mp->thread= 0;
- mp->count--;
-#ifdef __WIN__
- pthread_mutex_unlock(&mp->mutex);
- error=0;
-#else
- error=pthread_mutex_unlock(&mp->mutex);
- if (error)
- {
- fprintf(stderr,"safe_mutex: Got error: %d (%d) when trying to unlock mutex at %s, line %d\n", error, errno, file, line);
- fflush(stderr);
- abort();
- }
-#endif /* __WIN__ */
- pthread_mutex_unlock(&mp->global);
- return error;
-}
-
-
-int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file,
- uint line)
-{
- int error;
- pthread_mutex_lock(&mp->global);
- if (mp->count == 0)
- {
- fprintf(stderr,"safe_mutex: Trying to cond_wait on a unlocked mutex at %s, line %d\n",file,line);
- fflush(stderr);
- abort();
- }
- if (!pthread_equal(pthread_self(),mp->thread))
- {
- fprintf(stderr,"safe_mutex: Trying to cond_wait on a mutex at %s, line %d that was locked by another thread at: %s, line: %d\n",
- file,line,mp->file,mp->line);
- fflush(stderr);
- abort();
- }
-
- if (mp->count-- != 1)
- {
- fprintf(stderr,"safe_mutex: Count was %d on locked mutex at %s, line %d\n",
- mp->count+1, file, line);
- fflush(stderr);
- abort();
- }
- pthread_mutex_unlock(&mp->global);
- error=pthread_cond_wait(cond,&mp->mutex);
- pthread_mutex_lock(&mp->global);
- if (error)
- {
- fprintf(stderr,"safe_mutex: Got error: %d (%d) when doing a safe_mutex_wait at %s, line %d\n", error, errno, file, line);
- fflush(stderr);
- abort();
- }
- mp->thread=pthread_self();
- if (mp->count++)
- {
- fprintf(stderr,
- "safe_mutex: Count was %d in thread 0x%lx when locking mutex at %s, line %d\n",
- mp->count-1, my_thread_dbug_id(), file, line);
- fflush(stderr);
- abort();
- }
- mp->file= file;
- mp->line=line;
- pthread_mutex_unlock(&mp->global);
- return error;
-}
-
-
-int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
- const struct timespec *abstime,
- const char *file, uint line)
-{
- int error;
- pthread_mutex_lock(&mp->global);
- if (mp->count != 1 || !pthread_equal(pthread_self(),mp->thread))
- {
- fprintf(stderr,"safe_mutex: Trying to cond_wait at %s, line %d on a not hold mutex\n",file,line);
- fflush(stderr);
- abort();
- }
- mp->count--; /* Mutex will be released */
- pthread_mutex_unlock(&mp->global);
- error=pthread_cond_timedwait(cond,&mp->mutex,abstime);
-#ifdef EXTRA_DEBUG
- if (error && (error != EINTR && error != ETIMEDOUT && error != ETIME))
- {
- fprintf(stderr,"safe_mutex: Got error: %d (%d) when doing a safe_mutex_timedwait at %s, line %d\n", error, errno, file, line);
- }
-#endif
- pthread_mutex_lock(&mp->global);
- mp->thread=pthread_self();
- if (mp->count++)
- {
- fprintf(stderr,
- "safe_mutex: Count was %d in thread 0x%lx when locking mutex at %s, line %d (error: %d (%d))\n",
- mp->count-1, my_thread_dbug_id(), file, line, error, error);
- fflush(stderr);
- abort();
- }
- mp->file= file;
- mp->line=line;
- pthread_mutex_unlock(&mp->global);
- return error;
-}
-
-
-int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line)
-{
- int error=0;
- if (!mp->file)
- {
- fprintf(stderr,
- "safe_mutex: Trying to destroy unitialized mutex at %s, line %d\n",
- file, line);
- fflush(stderr);
- abort();
- }
- if (mp->count != 0)
- {
- fprintf(stderr,"safe_mutex: Trying to destroy a mutex that was locked at %s, line %d at %s, line %d\n",
- mp->file,mp->line, file, line);
- fflush(stderr);
- abort();
- }
-#ifdef __WIN__
- pthread_mutex_destroy(&mp->global);
- pthread_mutex_destroy(&mp->mutex);
-#else
- if (pthread_mutex_destroy(&mp->global))
- error=1;
- if (pthread_mutex_destroy(&mp->mutex))
- error=1;
-#endif
- mp->file= 0; /* Mark destroyed */
-
-#ifdef SAFE_MUTEX_DETECT_DESTROY
- if (mp->info)
- {
- struct st_safe_mutex_info_t *info= mp->info;
- pthread_mutex_lock(&THR_LOCK_mutex);
-
- if (info->prev)
- info->prev->next = info->next;
- else
- safe_mutex_root = info->next;
- if (info->next)
- info->next->prev = info->prev;
- safe_mutex_count--;
-
- pthread_mutex_unlock(&THR_LOCK_mutex);
- free(info);
- mp->info= NULL; /* Get crash if double free */
- }
-#else
- pthread_mutex_lock(&THR_LOCK_mutex);
- safe_mutex_count--;
- pthread_mutex_unlock(&THR_LOCK_mutex);
-#endif /* SAFE_MUTEX_DETECT_DESTROY */
- return error;
-}
-
-
-/*
- Free global resources and check that all mutex has been destroyed
-
- SYNOPSIS
- safe_mutex_end()
- file Print errors on this file
-
- NOTES
- We can't use DBUG_PRINT() here as we have in my_end() disabled
- DBUG handling before calling this function.
-
- In MySQL one may get one warning for a mutex created in my_thr_init.c
- This is ok, as this thread may not yet have been exited.
-*/
-
-void safe_mutex_end(FILE *file __attribute__((unused)))
-{
- if (!safe_mutex_count) /* safetly */
- pthread_mutex_destroy(&THR_LOCK_mutex);
-#ifdef SAFE_MUTEX_DETECT_DESTROY
- if (!file)
- return;
-
- if (safe_mutex_count)
- {
- fprintf(file, "Warning: Not destroyed mutex: %lu\n", safe_mutex_count);
- (void) fflush(file);
- }
- {
- struct st_safe_mutex_info_t *ptr;
- for (ptr= safe_mutex_root ; ptr ; ptr= ptr->next)
- {
- fprintf(file, "\tMutex initiated at line %4u in '%s'\n",
- ptr->init_line, ptr->init_file);
- (void) fflush(file);
- }
- }
-#endif /* SAFE_MUTEX_DETECT_DESTROY */
-}
-
-#endif /* SAFE_MUTEX */
-
-#if 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
-
-static int cpu_count= 0;
-
-int my_pthread_fastmutex_init(my_pthread_fastmutex_t *mp,
- const pthread_mutexattr_t *attr)
-{
- if ((cpu_count > 1) && (attr == MY_MUTEX_INIT_FAST))
- mp->spins= MY_PTHREAD_FASTMUTEX_SPINS;
- else
- mp->spins= 0;
- mp->rng_state= 1;
- return pthread_mutex_init(&mp->mutex, attr);
-}
-
-/**
- Park-Miller random number generator. A simple linear congruential
- generator that operates in multiplicative group of integers modulo n.
-
- x_{k+1} = (x_k g) mod n
-
- Popular pair of parameters: n = 2^32 − 5 = 4294967291 and g = 279470273.
- The period of the generator is about 2^31.
- Largest value that can be returned: 2147483646 (RAND_MAX)
-
- Reference:
-
- S. K. Park and K. W. Miller
- "Random number generators: good ones are hard to find"
- Commun. ACM, October 1988, Volume 31, No 10, pages 1192-1201.
-*/
-
-static double park_rng(my_pthread_fastmutex_t *mp)
-{
- mp->rng_state= ((my_ulonglong)mp->rng_state * 279470273U) % 4294967291U;
- return (mp->rng_state / 2147483647.0);
-}
-
-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 += park_rng(mp) * MY_PTHREAD_FASTMUTEX_DELAY + 1;
- }
- return pthread_mutex_lock(&mp->mutex);
-}
-
-
-void fastmutex_global_init(void)
-{
-#ifdef _SC_NPROCESSORS_CONF
- cpu_count= sysconf(_SC_NPROCESSORS_CONF);
-#endif
-}
-
-#endif /* defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) */
diff --git a/dep/mysqllite/mysys/thr_rwlock.c b/dep/mysqllite/mysys/thr_rwlock.c
deleted file mode 100644
index bad80b43eef..00000000000
--- a/dep/mysqllite/mysys/thr_rwlock.c
+++ /dev/null
@@ -1,472 +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 */
-
-/* Synchronization - readers / writer thread locks */
-
-#include "mysys_priv.h"
-#if defined(NEED_MY_RW_LOCK)
-#include <errno.h>
-
-#ifdef _WIN32
-
-static BOOL have_srwlock= FALSE;
-/* Prototypes and function pointers for windows functions */
-typedef VOID (WINAPI* srw_func) (PSRWLOCK SRWLock);
-typedef BOOL (WINAPI* srw_bool_func) (PSRWLOCK SRWLock);
-
-static srw_func my_InitializeSRWLock;
-static srw_func my_AcquireSRWLockExclusive;
-static srw_func my_ReleaseSRWLockExclusive;
-static srw_func my_AcquireSRWLockShared;
-static srw_func my_ReleaseSRWLockShared;
-
-static srw_bool_func my_TryAcquireSRWLockExclusive;
-static srw_bool_func my_TryAcquireSRWLockShared;
-
-/**
- Check for presence of Windows slim reader writer lock function.
- Load function pointers.
-*/
-
-static void check_srwlock_availability(void)
-{
- HMODULE module= GetModuleHandle("kernel32");
-
- my_InitializeSRWLock= (srw_func) GetProcAddress(module,
- "InitializeSRWLock");
- my_AcquireSRWLockExclusive= (srw_func) GetProcAddress(module,
- "AcquireSRWLockExclusive");
- my_AcquireSRWLockShared= (srw_func) GetProcAddress(module,
- "AcquireSRWLockShared");
- my_ReleaseSRWLockExclusive= (srw_func) GetProcAddress(module,
- "ReleaseSRWLockExclusive");
- my_ReleaseSRWLockShared= (srw_func) GetProcAddress(module,
- "ReleaseSRWLockShared");
- my_TryAcquireSRWLockExclusive= (srw_bool_func) GetProcAddress(module,
- "TryAcquireSRWLockExclusive");
- my_TryAcquireSRWLockShared= (srw_bool_func) GetProcAddress(module,
- "TryAcquireSRWLockShared");
-
- /*
- We currently require TryAcquireSRWLockExclusive. This API is missing on
- Vista, this means SRWLock are only used starting with Win7.
-
- If "trylock" usage for rwlocks is eliminated from server codebase (it is used
- in a single place currently, in query cache), then SRWLock can be enabled on
- Vista too. In this case condition below needs to be changed to e.g check
- for my_InitializeSRWLock.
- */
-
- if (my_TryAcquireSRWLockExclusive)
- have_srwlock= TRUE;
-
-}
-
-
-static int srw_init(my_rw_lock_t *rwp)
-{
- my_InitializeSRWLock(&rwp->srwlock);
- rwp->have_exclusive_srwlock = FALSE;
- return 0;
-}
-
-
-static int srw_rdlock(my_rw_lock_t *rwp)
-{
- my_AcquireSRWLockShared(&rwp->srwlock);
- return 0;
-}
-
-
-static int srw_tryrdlock(my_rw_lock_t *rwp)
-{
-
- if (!my_TryAcquireSRWLockShared(&rwp->srwlock))
- return EBUSY;
- return 0;
-}
-
-
-static int srw_wrlock(my_rw_lock_t *rwp)
-{
- my_AcquireSRWLockExclusive(&rwp->srwlock);
- rwp->have_exclusive_srwlock= TRUE;
- return 0;
-}
-
-
-static int srw_trywrlock(my_rw_lock_t *rwp)
-{
- if (!my_TryAcquireSRWLockExclusive(&rwp->srwlock))
- return EBUSY;
- rwp->have_exclusive_srwlock= TRUE;
- return 0;
-}
-
-
-static int srw_unlock(my_rw_lock_t *rwp)
-{
- if (rwp->have_exclusive_srwlock)
- {
- rwp->have_exclusive_srwlock= FALSE;
- my_ReleaseSRWLockExclusive(&rwp->srwlock);
- }
- else
- {
- my_ReleaseSRWLockShared(&rwp->srwlock);
- }
- return 0;
-}
-
-#endif /*_WIN32 */
-
-/*
- Source base from Sun Microsystems SPILT, simplified for MySQL use
- -- Joshua Chamas
- Some cleanup and additional code by Monty
-*/
-
-/*
-* Multithreaded Demo Source
-*
-* Copyright (C) 1995 by Sun Microsystems, Inc.
-* All rights reserved.
-*
-* This file is a product of SunSoft, Inc. and is provided for
-* unrestricted use provided that this legend is included on all
-* media and as a part of the software program in whole or part.
-* Users may copy, modify or distribute this file at will.
-*
-* THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
-* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
-* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
-*
-* This file is provided with no support and without any obligation on the
-* part of SunSoft, Inc. to assist in its use, correction, modification or
-* enhancement.
-*
-* SUNSOFT AND SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT
-* TO THE INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS
-* FILE OR ANY PART THEREOF.
-*
-* IN NO EVENT WILL SUNSOFT OR SUN MICROSYSTEMS, INC. BE LIABLE FOR ANY
-* LOST REVENUE OR PROFITS OR OTHER SPECIAL, INDIRECT AND CONSEQUENTIAL
-* DAMAGES, EVEN IF THEY HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
-* DAMAGES.
-*
-* SunSoft, Inc.
-* 2550 Garcia Avenue
-* Mountain View, California 94043
-*/
-
-int my_rw_init(my_rw_lock_t *rwp)
-{
- pthread_condattr_t cond_attr;
-
-#ifdef _WIN32
- /*
- Once initialization is used here rather than in my_init(), in order to
- - avoid my_init() pitfalls- (undefined order in which initialization should
- run)
- - be potentially useful C++ (static constructors)
- - just to simplify the API.
- Also, the overhead is of my_pthread_once is very small.
- */
- static my_pthread_once_t once_control= MY_PTHREAD_ONCE_INIT;
- my_pthread_once(&once_control, check_srwlock_availability);
-
- if (have_srwlock)
- return srw_init(rwp);
-#endif
-
- pthread_mutex_init( &rwp->lock, MY_MUTEX_INIT_FAST);
- pthread_condattr_init( &cond_attr );
- pthread_cond_init( &rwp->readers, &cond_attr );
- pthread_cond_init( &rwp->writers, &cond_attr );
- pthread_condattr_destroy(&cond_attr);
-
- rwp->state = 0;
- rwp->waiters = 0;
-#ifdef SAFE_MUTEX
- rwp->write_thread = 0;
-#endif
-
- return(0);
-}
-
-
-int my_rw_destroy(my_rw_lock_t *rwp)
-{
-#ifdef _WIN32
- if (have_srwlock)
- return 0; /* no destroy function */
-#endif
- DBUG_ASSERT(rwp->state == 0);
- pthread_mutex_destroy( &rwp->lock );
- pthread_cond_destroy( &rwp->readers );
- pthread_cond_destroy( &rwp->writers );
- return(0);
-}
-
-
-int my_rw_rdlock(my_rw_lock_t *rwp)
-{
-#ifdef _WIN32
- if (have_srwlock)
- return srw_rdlock(rwp);
-#endif
-
- pthread_mutex_lock(&rwp->lock);
-
- /* active or queued writers */
- while (( rwp->state < 0 ) || rwp->waiters)
- pthread_cond_wait( &rwp->readers, &rwp->lock);
-
- rwp->state++;
- pthread_mutex_unlock(&rwp->lock);
- return(0);
-}
-
-int my_rw_tryrdlock(my_rw_lock_t *rwp)
-{
- int res;
-
-#ifdef _WIN32
- if (have_srwlock)
- return srw_tryrdlock(rwp);
-#endif
-
- pthread_mutex_lock(&rwp->lock);
- if ((rwp->state < 0 ) || rwp->waiters)
- res= EBUSY; /* Can't get lock */
- else
- {
- res=0;
- rwp->state++;
- }
- pthread_mutex_unlock(&rwp->lock);
- return(res);
-}
-
-
-int my_rw_wrlock(my_rw_lock_t *rwp)
-{
-#ifdef _WIN32
- if (have_srwlock)
- return srw_wrlock(rwp);
-#endif
-
- pthread_mutex_lock(&rwp->lock);
- rwp->waiters++; /* another writer queued */
-
- my_rw_lock_assert_not_write_owner(rwp);
-
- while (rwp->state)
- pthread_cond_wait(&rwp->writers, &rwp->lock);
- rwp->state = -1;
- rwp->waiters--;
-#ifdef SAFE_MUTEX
- rwp->write_thread= pthread_self();
-#endif
- pthread_mutex_unlock(&rwp->lock);
- return(0);
-}
-
-
-int my_rw_trywrlock(my_rw_lock_t *rwp)
-{
- int res;
-
-#ifdef _WIN32
- if (have_srwlock)
- return srw_trywrlock(rwp);
-#endif
-
- pthread_mutex_lock(&rwp->lock);
- if (rwp->state)
- res= EBUSY; /* Can't get lock */
- else
- {
- res=0;
- rwp->state = -1;
-#ifdef SAFE_MUTEX
- rwp->write_thread= pthread_self();
-#endif
- }
- pthread_mutex_unlock(&rwp->lock);
- return(res);
-}
-
-
-int my_rw_unlock(my_rw_lock_t *rwp)
-{
-#ifdef _WIN32
- if (have_srwlock)
- return srw_unlock(rwp);
-#endif
-
- DBUG_PRINT("rw_unlock",
- ("state: %d waiters: %d", rwp->state, rwp->waiters));
- pthread_mutex_lock(&rwp->lock);
-
- DBUG_ASSERT(rwp->state != 0);
-
- if (rwp->state == -1) /* writer releasing */
- {
- my_rw_lock_assert_write_owner(rwp);
- rwp->state= 0; /* mark as available */
-#ifdef SAFE_MUTEX
- rwp->write_thread= 0;
-#endif
-
- if ( rwp->waiters ) /* writers queued */
- pthread_cond_signal( &rwp->writers );
- else
- pthread_cond_broadcast( &rwp->readers );
- }
- else
- {
- if ( --rwp->state == 0 && /* no more readers */
- rwp->waiters)
- pthread_cond_signal( &rwp->writers );
- }
-
- pthread_mutex_unlock( &rwp->lock );
- return(0);
-}
-
-#endif /* defined(NEED_MY_RW_LOCK) */
-
-
-int rw_pr_init(rw_pr_lock_t *rwlock)
-{
- pthread_mutex_init(&rwlock->lock, NULL);
- pthread_cond_init(&rwlock->no_active_readers, NULL);
- rwlock->active_readers= 0;
- rwlock->writers_waiting_readers= 0;
- rwlock->active_writer= FALSE;
-#ifdef SAFE_MUTEX
- rwlock->writer_thread= 0;
-#endif
- return 0;
-}
-
-
-int rw_pr_destroy(rw_pr_lock_t *rwlock)
-{
- pthread_cond_destroy(&rwlock->no_active_readers);
- pthread_mutex_destroy(&rwlock->lock);
- return 0;
-}
-
-
-int rw_pr_rdlock(rw_pr_lock_t *rwlock)
-{
- pthread_mutex_lock(&rwlock->lock);
- /*
- The fact that we were able to acquire 'lock' mutex means
- that there are no active writers and we can acquire rd-lock.
- Increment active readers counter to prevent requests for
- wr-lock from succeeding and unlock mutex.
- */
- rwlock->active_readers++;
- pthread_mutex_unlock(&rwlock->lock);
- return 0;
-}
-
-
-int rw_pr_wrlock(rw_pr_lock_t *rwlock)
-{
- pthread_mutex_lock(&rwlock->lock);
-
- if (rwlock->active_readers != 0)
- {
- /* There are active readers. We have to wait until they are gone. */
- rwlock->writers_waiting_readers++;
-
- while (rwlock->active_readers != 0)
- pthread_cond_wait(&rwlock->no_active_readers, &rwlock->lock);
-
- rwlock->writers_waiting_readers--;
- }
-
- /*
- We own 'lock' mutex so there is no active writers.
- Also there are no active readers.
- This means that we can grant wr-lock.
- Not releasing 'lock' mutex until unlock will block
- both requests for rd and wr-locks.
- Set 'active_writer' flag to simplify unlock.
-
- Thanks to the fact wr-lock/unlock in the absence of
- contention from readers is essentially mutex lock/unlock
- with a few simple checks make this rwlock implementation
- wr-lock optimized.
- */
- rwlock->active_writer= TRUE;
-#ifdef SAFE_MUTEX
- rwlock->writer_thread= pthread_self();
-#endif
- return 0;
-}
-
-
-int rw_pr_unlock(rw_pr_lock_t *rwlock)
-{
- if (rwlock->active_writer)
- {
- /* We are unlocking wr-lock. */
-#ifdef SAFE_MUTEX
- rwlock->writer_thread= 0;
-#endif
- rwlock->active_writer= FALSE;
- if (rwlock->writers_waiting_readers)
- {
- /*
- Avoid expensive cond signal in case when there is no contention
- or it is wr-only.
-
- Note that from view point of performance it would be better to
- signal on the condition variable after unlocking mutex (as it
- reduces number of contex switches).
-
- Unfortunately this would mean that such rwlock can't be safely
- used by MDL subsystem, which relies on the fact that it is OK
- to destroy rwlock once it is in unlocked state.
- */
- pthread_cond_signal(&rwlock->no_active_readers);
- }
- pthread_mutex_unlock(&rwlock->lock);
- }
- else
- {
- /* We are unlocking rd-lock. */
- pthread_mutex_lock(&rwlock->lock);
- rwlock->active_readers--;
- if (rwlock->active_readers == 0 &&
- rwlock->writers_waiting_readers)
- {
- /*
- If we are last reader and there are waiting
- writers wake them up.
- */
- pthread_cond_signal(&rwlock->no_active_readers);
- }
- pthread_mutex_unlock(&rwlock->lock);
- }
- return 0;
-}
-
-
diff --git a/dep/mysqllite/mysys/tree.c b/dep/mysqllite/mysys/tree.c
deleted file mode 100644
index 8ea7102ed4c..00000000000
--- a/dep/mysqllite/mysys/tree.c
+++ /dev/null
@@ -1,757 +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 */
-
-/*
- Code for handling red-black (balanced) binary trees.
- key in tree is allocated accrding to following:
-
- 1) If size < 0 then tree will not allocate keys and only a pointer to
- each key is saved in tree.
- compare and search functions uses and returns key-pointer
-
- 2) If size == 0 then there are two options:
- - key_size != 0 to tree_insert: The key will be stored in the tree.
- - key_size == 0 to tree_insert: A pointer to the key is stored.
- compare and search functions uses and returns key-pointer.
-
- 3) if key_size is given to init_tree then each node will continue the
- key and calls to insert_key may increase length of key.
- if key_size > sizeof(pointer) and key_size is a multiple of 8 (double
- allign) then key will be put on a 8 alligned adress. Else
- the key will be on adress (element+1). This is transparent for user
- compare and search functions uses a pointer to given key-argument.
-
- - If you use a free function for tree-elements and you are freeing
- the element itself, you should use key_size = 0 to init_tree and
- tree_search
-
- The actual key in TREE_ELEMENT is saved as a pointer or after the
- TREE_ELEMENT struct.
- If one uses only pointers in tree one can use tree_set_pointer() to
- change address of data.
-
- Implemented by monty.
-*/
-
-/*
- NOTE:
- tree->compare function should be ALWAYS called as
- (*tree->compare)(custom_arg, ELEMENT_KEY(tree,element), key)
- and not other way around, as
- (*tree->compare)(custom_arg, key, ELEMENT_KEY(tree,element))
-
- ft_boolean_search.c (at least) relies on that.
-*/
-
-#include "mysys_priv.h"
-#include <m_string.h>
-#include <my_tree.h>
-#include "my_base.h"
-
-#define BLACK 1
-#define RED 0
-#define DEFAULT_ALLOC_SIZE 8192
-#define DEFAULT_ALIGN_SIZE 8192
-
-static void delete_tree_element(TREE *,TREE_ELEMENT *);
-static int tree_walk_left_root_right(TREE *,TREE_ELEMENT *,
- tree_walk_action,void *);
-static int tree_walk_right_root_left(TREE *,TREE_ELEMENT *,
- tree_walk_action,void *);
-static void left_rotate(TREE_ELEMENT **parent,TREE_ELEMENT *leaf);
-static void right_rotate(TREE_ELEMENT **parent, TREE_ELEMENT *leaf);
-static void rb_insert(TREE *tree,TREE_ELEMENT ***parent,
- TREE_ELEMENT *leaf);
-static void rb_delete_fixup(TREE *tree,TREE_ELEMENT ***parent);
-
-
- /* The actuall code for handling binary trees */
-
-#ifndef DBUG_OFF
-static int test_rb_tree(TREE_ELEMENT *element);
-#endif
-
-void init_tree(TREE *tree, ulong default_alloc_size, ulong memory_limit,
- int size, qsort_cmp2 compare, my_bool with_delete,
- tree_element_free free_element, void *custom_arg)
-{
- DBUG_ENTER("init_tree");
- DBUG_PRINT("enter",("tree: 0x%lx size: %d", (long) tree, size));
-
- if (default_alloc_size < DEFAULT_ALLOC_SIZE)
- default_alloc_size= DEFAULT_ALLOC_SIZE;
- default_alloc_size= MY_ALIGN(default_alloc_size, DEFAULT_ALIGN_SIZE);
- bzero((uchar*) &tree->null_element,sizeof(tree->null_element));
- tree->root= &tree->null_element;
- tree->compare=compare;
- tree->size_of_element=size > 0 ? (uint) size : 0;
- tree->memory_limit=memory_limit;
- tree->free=free_element;
- tree->allocated=0;
- tree->elements_in_tree=0;
- tree->custom_arg = custom_arg;
- tree->null_element.colour=BLACK;
- tree->null_element.left=tree->null_element.right=0;
- tree->flag= 0;
- if (!free_element && size >= 0 &&
- ((uint) size <= sizeof(void*) || ((uint) size & (sizeof(void*)-1))))
- {
- /*
- We know that the data doesn't have to be aligned (like if the key
- contains a double), so we can store the data combined with the
- TREE_ELEMENT.
- */
- tree->offset_to_key=sizeof(TREE_ELEMENT); /* Put key after element */
- /* Fix allocation size so that we don't lose any memory */
- default_alloc_size/=(sizeof(TREE_ELEMENT)+size);
- if (!default_alloc_size)
- default_alloc_size=1;
- default_alloc_size*=(sizeof(TREE_ELEMENT)+size);
- }
- else
- {
- tree->offset_to_key=0; /* use key through pointer */
- tree->size_of_element+=sizeof(void*);
- }
- if (!(tree->with_delete=with_delete))
- {
- init_alloc_root(&tree->mem_root, (uint) default_alloc_size, 0);
- tree->mem_root.min_malloc=(sizeof(TREE_ELEMENT)+tree->size_of_element);
- }
- DBUG_VOID_RETURN;
-}
-
-static void free_tree(TREE *tree, myf free_flags)
-{
- DBUG_ENTER("free_tree");
- DBUG_PRINT("enter",("tree: 0x%lx", (long) tree));
-
- if (tree->root) /* If initialized */
- {
- if (tree->with_delete)
- delete_tree_element(tree,tree->root);
- else
- {
- if (tree->free)
- {
- if (tree->memory_limit)
- (*tree->free)(NULL, free_init, tree->custom_arg);
- delete_tree_element(tree,tree->root);
- if (tree->memory_limit)
- (*tree->free)(NULL, free_end, tree->custom_arg);
- }
- free_root(&tree->mem_root, free_flags);
- }
- }
- tree->root= &tree->null_element;
- tree->elements_in_tree=0;
- tree->allocated=0;
-
- DBUG_VOID_RETURN;
-}
-
-void delete_tree(TREE* tree)
-{
- free_tree(tree, MYF(0)); /* my_free() mem_root if applicable */
-}
-
-void reset_tree(TREE* tree)
-{
- /* do not free mem_root, just mark blocks as free */
- free_tree(tree, MYF(MY_MARK_BLOCKS_FREE));
-}
-
-
-static void delete_tree_element(TREE *tree, TREE_ELEMENT *element)
-{
- if (element != &tree->null_element)
- {
- delete_tree_element(tree,element->left);
- if (tree->free)
- (*tree->free)(ELEMENT_KEY(tree,element), free_free, tree->custom_arg);
- delete_tree_element(tree,element->right);
- if (tree->with_delete)
- my_free(element);
- }
-}
-
-
-/*
- insert, search and delete of elements
-
- The following should be true:
- parent[0] = & parent[-1][0]->left ||
- parent[0] = & parent[-1][0]->right
-*/
-
-TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size,
- void* custom_arg)
-{
- int cmp;
- TREE_ELEMENT *element,***parent;
-
- parent= tree->parents;
- *parent = &tree->root; element= tree->root;
- for (;;)
- {
- if (element == &tree->null_element ||
- (cmp = (*tree->compare)(custom_arg, ELEMENT_KEY(tree,element),
- key)) == 0)
- break;
- if (cmp < 0)
- {
- *++parent= &element->right; element= element->right;
- }
- else
- {
- *++parent = &element->left; element= element->left;
- }
- }
- if (element == &tree->null_element)
- {
- uint alloc_size=sizeof(TREE_ELEMENT)+key_size+tree->size_of_element;
- tree->allocated+=alloc_size;
-
- if (tree->memory_limit && tree->elements_in_tree
- && tree->allocated > tree->memory_limit)
- {
- reset_tree(tree);
- return tree_insert(tree, key, key_size, custom_arg);
- }
-
- key_size+=tree->size_of_element;
- if (tree->with_delete)
- element=(TREE_ELEMENT *) my_malloc(alloc_size, MYF(MY_WME));
- else
- element=(TREE_ELEMENT *) alloc_root(&tree->mem_root,alloc_size);
- if (!element)
- return(NULL);
- **parent=element;
- element->left=element->right= &tree->null_element;
- if (!tree->offset_to_key)
- {
- if (key_size == sizeof(void*)) /* no length, save pointer */
- *((void**) (element+1))=key;
- else
- {
- *((void**) (element+1))= (void*) ((void **) (element+1)+1);
- memcpy((uchar*) *((void **) (element+1)),key,
- (size_t) (key_size-sizeof(void*)));
- }
- }
- else
- memcpy((uchar*) element+tree->offset_to_key,key,(size_t) key_size);
- element->count=1; /* May give warning in purify */
- tree->elements_in_tree++;
- rb_insert(tree,parent,element); /* rebalance tree */
- }
- else
- {
- if (tree->flag & TREE_NO_DUPS)
- return(NULL);
- element->count++;
- /* Avoid a wrap over of the count. */
- if (! element->count)
- element->count--;
- }
- DBUG_EXECUTE("check_tree", test_rb_tree(tree->root););
- return element;
-}
-
-int tree_delete(TREE *tree, void *key, uint key_size, void *custom_arg)
-{
- int cmp,remove_colour;
- TREE_ELEMENT *element,***parent, ***org_parent, *nod;
- if (!tree->with_delete)
- return 1; /* not allowed */
-
- parent= tree->parents;
- *parent= &tree->root; element= tree->root;
- for (;;)
- {
- if (element == &tree->null_element)
- return 1; /* Was not in tree */
- if ((cmp = (*tree->compare)(custom_arg, ELEMENT_KEY(tree,element),
- key)) == 0)
- break;
- if (cmp < 0)
- {
- *++parent= &element->right; element= element->right;
- }
- else
- {
- *++parent = &element->left; element= element->left;
- }
- }
- if (element->left == &tree->null_element)
- {
- (**parent)=element->right;
- remove_colour= element->colour;
- }
- else if (element->right == &tree->null_element)
- {
- (**parent)=element->left;
- remove_colour= element->colour;
- }
- else
- {
- org_parent= parent;
- *++parent= &element->right; nod= element->right;
- while (nod->left != &tree->null_element)
- {
- *++parent= &nod->left; nod= nod->left;
- }
- (**parent)=nod->right; /* unlink nod from tree */
- remove_colour= nod->colour;
- org_parent[0][0]=nod; /* put y in place of element */
- org_parent[1]= &nod->right;
- nod->left=element->left;
- nod->right=element->right;
- nod->colour=element->colour;
- }
- if (remove_colour == BLACK)
- rb_delete_fixup(tree,parent);
- if (tree->free)
- (*tree->free)(ELEMENT_KEY(tree,element), free_free, tree->custom_arg);
- tree->allocated-= sizeof(TREE_ELEMENT) + tree->size_of_element + key_size;
- my_free(element);
- tree->elements_in_tree--;
- return 0;
-}
-
-
-void *tree_search(TREE *tree, void *key, void *custom_arg)
-{
- int cmp;
- TREE_ELEMENT *element=tree->root;
-
- for (;;)
- {
- if (element == &tree->null_element)
- return (void*) 0;
- if ((cmp = (*tree->compare)(custom_arg, ELEMENT_KEY(tree,element),
- key)) == 0)
- return ELEMENT_KEY(tree,element);
- if (cmp < 0)
- element=element->right;
- else
- element=element->left;
- }
-}
-
-void *tree_search_key(TREE *tree, const void *key,
- TREE_ELEMENT **parents, TREE_ELEMENT ***last_pos,
- enum ha_rkey_function flag, void *custom_arg)
-{
- int cmp;
- TREE_ELEMENT *element= tree->root;
- TREE_ELEMENT **last_left_step_parent= NULL, **last_right_step_parent= NULL;
- TREE_ELEMENT **last_equal_element= NULL;
-
-/*
- TODO: support for HA_READ_KEY_OR_PREV, HA_READ_PREFIX flags if needed.
-*/
-
- *parents = &tree->null_element;
- while (element != &tree->null_element)
- {
- *++parents= element;
- if ((cmp= (*tree->compare)(custom_arg, ELEMENT_KEY(tree, element),
- key)) == 0)
- {
- switch (flag) {
- case HA_READ_KEY_EXACT:
- case HA_READ_KEY_OR_NEXT:
- case HA_READ_BEFORE_KEY:
- last_equal_element= parents;
- cmp= 1;
- break;
- case HA_READ_AFTER_KEY:
- cmp= -1;
- break;
- case HA_READ_PREFIX_LAST:
- case HA_READ_PREFIX_LAST_OR_PREV:
- last_equal_element= parents;
- cmp= -1;
- break;
- default:
- return NULL;
- }
- }
- if (cmp < 0) /* element < key */
- {
- last_right_step_parent= parents;
- element= element->right;
- }
- else
- {
- last_left_step_parent= parents;
- element= element->left;
- }
- }
- switch (flag) {
- case HA_READ_KEY_EXACT:
- case HA_READ_PREFIX_LAST:
- *last_pos= last_equal_element;
- break;
- case HA_READ_KEY_OR_NEXT:
- *last_pos= last_equal_element ? last_equal_element : last_left_step_parent;
- break;
- case HA_READ_AFTER_KEY:
- *last_pos= last_left_step_parent;
- break;
- case HA_READ_PREFIX_LAST_OR_PREV:
- *last_pos= last_equal_element ? last_equal_element : last_right_step_parent;
- break;
- case HA_READ_BEFORE_KEY:
- *last_pos= last_right_step_parent;
- break;
- default:
- return NULL;
- }
- return *last_pos ? ELEMENT_KEY(tree, **last_pos) : NULL;
-}
-
-/*
- Search first (the most left) or last (the most right) tree element
-*/
-void *tree_search_edge(TREE *tree, TREE_ELEMENT **parents,
- TREE_ELEMENT ***last_pos, int child_offs)
-{
- TREE_ELEMENT *element= tree->root;
-
- *parents= &tree->null_element;
- while (element != &tree->null_element)
- {
- *++parents= element;
- element= ELEMENT_CHILD(element, child_offs);
- }
- *last_pos= parents;
- return **last_pos != &tree->null_element ?
- ELEMENT_KEY(tree, **last_pos) : NULL;
-}
-
-void *tree_search_next(TREE *tree, TREE_ELEMENT ***last_pos, int l_offs,
- int r_offs)
-{
- TREE_ELEMENT *x= **last_pos;
-
- if (ELEMENT_CHILD(x, r_offs) != &tree->null_element)
- {
- x= ELEMENT_CHILD(x, r_offs);
- *++*last_pos= x;
- while (ELEMENT_CHILD(x, l_offs) != &tree->null_element)
- {
- x= ELEMENT_CHILD(x, l_offs);
- *++*last_pos= x;
- }
- return ELEMENT_KEY(tree, x);
- }
- else
- {
- TREE_ELEMENT *y= *--*last_pos;
- while (y != &tree->null_element && x == ELEMENT_CHILD(y, r_offs))
- {
- x= y;
- y= *--*last_pos;
- }
- return y == &tree->null_element ? NULL : ELEMENT_KEY(tree, y);
- }
-}
-
-/*
- Expected that tree is fully balanced
- (each path from root to leaf has the same length)
-*/
-ha_rows tree_record_pos(TREE *tree, const void *key,
- enum ha_rkey_function flag, void *custom_arg)
-{
- int cmp;
- TREE_ELEMENT *element= tree->root;
- double left= 1;
- double right= tree->elements_in_tree;
-
- while (element != &tree->null_element)
- {
- if ((cmp= (*tree->compare)(custom_arg, ELEMENT_KEY(tree, element),
- key)) == 0)
- {
- switch (flag) {
- case HA_READ_KEY_EXACT:
- case HA_READ_BEFORE_KEY:
- cmp= 1;
- break;
- case HA_READ_AFTER_KEY:
- cmp= -1;
- break;
- default:
- return HA_POS_ERROR;
- }
- }
- if (cmp < 0) /* element < key */
- {
- element= element->right;
- left= (left + right) / 2;
- }
- else
- {
- element= element->left;
- right= (left + right) / 2;
- }
- }
- switch (flag) {
- case HA_READ_KEY_EXACT:
- case HA_READ_BEFORE_KEY:
- return (ha_rows) right;
- case HA_READ_AFTER_KEY:
- return (ha_rows) left;
- default:
- return HA_POS_ERROR;
- }
-}
-
-int tree_walk(TREE *tree, tree_walk_action action, void *argument, TREE_WALK visit)
-{
- switch (visit) {
- case left_root_right:
- return tree_walk_left_root_right(tree,tree->root,action,argument);
- case right_root_left:
- return tree_walk_right_root_left(tree,tree->root,action,argument);
- }
- return 0; /* Keep gcc happy */
-}
-
-static int tree_walk_left_root_right(TREE *tree, TREE_ELEMENT *element, tree_walk_action action, void *argument)
-{
- int error;
- if (element->left) /* Not null_element */
- {
- if ((error=tree_walk_left_root_right(tree,element->left,action,
- argument)) == 0 &&
- (error=(*action)(ELEMENT_KEY(tree,element),
- (element_count) element->count,
- argument)) == 0)
- error=tree_walk_left_root_right(tree,element->right,action,argument);
- return error;
- }
- return 0;
-}
-
-static int tree_walk_right_root_left(TREE *tree, TREE_ELEMENT *element, tree_walk_action action, void *argument)
-{
- int error;
- if (element->right) /* Not null_element */
- {
- if ((error=tree_walk_right_root_left(tree,element->right,action,
- argument)) == 0 &&
- (error=(*action)(ELEMENT_KEY(tree,element),
- (element_count) element->count,
- argument)) == 0)
- error=tree_walk_right_root_left(tree,element->left,action,argument);
- return error;
- }
- return 0;
-}
-
-
- /* Functions to fix up the tree after insert and delete */
-
-static void left_rotate(TREE_ELEMENT **parent, TREE_ELEMENT *leaf)
-{
- TREE_ELEMENT *y;
-
- y=leaf->right;
- leaf->right=y->left;
- parent[0]=y;
- y->left=leaf;
-}
-
-static void right_rotate(TREE_ELEMENT **parent, TREE_ELEMENT *leaf)
-{
- TREE_ELEMENT *x;
-
- x=leaf->left;
- leaf->left=x->right;
- parent[0]=x;
- x->right=leaf;
-}
-
-static void rb_insert(TREE *tree, TREE_ELEMENT ***parent, TREE_ELEMENT *leaf)
-{
- TREE_ELEMENT *y,*par,*par2;
-
- leaf->colour=RED;
- while (leaf != tree->root && (par=parent[-1][0])->colour == RED)
- {
- if (par == (par2=parent[-2][0])->left)
- {
- y= par2->right;
- if (y->colour == RED)
- {
- par->colour=BLACK;
- y->colour=BLACK;
- leaf=par2;
- parent-=2;
- leaf->colour=RED; /* And the loop continues */
- }
- else
- {
- if (leaf == par->right)
- {
- left_rotate(parent[-1],par);
- par=leaf; /* leaf is now parent to old leaf */
- }
- par->colour=BLACK;
- par2->colour=RED;
- right_rotate(parent[-2],par2);
- break;
- }
- }
- else
- {
- y= par2->left;
- if (y->colour == RED)
- {
- par->colour=BLACK;
- y->colour=BLACK;
- leaf=par2;
- parent-=2;
- leaf->colour=RED; /* And the loop continues */
- }
- else
- {
- if (leaf == par->left)
- {
- right_rotate(parent[-1],par);
- par=leaf;
- }
- par->colour=BLACK;
- par2->colour=RED;
- left_rotate(parent[-2],par2);
- break;
- }
- }
- }
- tree->root->colour=BLACK;
-}
-
-static void rb_delete_fixup(TREE *tree, TREE_ELEMENT ***parent)
-{
- TREE_ELEMENT *x,*w,*par;
-
- x= **parent;
- while (x != tree->root && x->colour == BLACK)
- {
- if (x == (par=parent[-1][0])->left)
- {
- w=par->right;
- if (w->colour == RED)
- {
- w->colour=BLACK;
- par->colour=RED;
- left_rotate(parent[-1],par);
- parent[0]= &w->left;
- *++parent= &par->left;
- w=par->right;
- }
- if (w->left->colour == BLACK && w->right->colour == BLACK)
- {
- w->colour=RED;
- x=par;
- parent--;
- }
- else
- {
- if (w->right->colour == BLACK)
- {
- w->left->colour=BLACK;
- w->colour=RED;
- right_rotate(&par->right,w);
- w=par->right;
- }
- w->colour=par->colour;
- par->colour=BLACK;
- w->right->colour=BLACK;
- left_rotate(parent[-1],par);
- x=tree->root;
- break;
- }
- }
- else
- {
- w=par->left;
- if (w->colour == RED)
- {
- w->colour=BLACK;
- par->colour=RED;
- right_rotate(parent[-1],par);
- parent[0]= &w->right;
- *++parent= &par->right;
- w=par->left;
- }
- if (w->right->colour == BLACK && w->left->colour == BLACK)
- {
- w->colour=RED;
- x=par;
- parent--;
- }
- else
- {
- if (w->left->colour == BLACK)
- {
- w->right->colour=BLACK;
- w->colour=RED;
- left_rotate(&par->left,w);
- w=par->left;
- }
- w->colour=par->colour;
- par->colour=BLACK;
- w->left->colour=BLACK;
- right_rotate(parent[-1],par);
- x=tree->root;
- break;
- }
- }
- }
- x->colour=BLACK;
-}
-
-#ifndef DBUG_OFF
-
- /* Test that the proporties for a red-black tree holds */
-
-static int test_rb_tree(TREE_ELEMENT *element)
-{
- int count_l,count_r;
-
- if (!element->left)
- return 0; /* Found end of tree */
- if (element->colour == RED &&
- (element->left->colour == RED || element->right->colour == RED))
- {
- printf("Wrong tree: Found two red in a row\n");
- return -1;
- }
- count_l=test_rb_tree(element->left);
- count_r=test_rb_tree(element->right);
- if (count_l >= 0 && count_r >= 0)
- {
- if (count_l == count_r)
- return count_l+(element->colour == BLACK);
- printf("Wrong tree: Incorrect black-count: %d - %d\n",count_l,count_r);
- }
- return -1;
-}
-#endif
diff --git a/dep/mysqllite/mysys/typelib.c b/dep/mysqllite/mysys/typelib.c
deleted file mode 100644
index 7681ff581ac..00000000000
--- a/dep/mysqllite/mysys/typelib.c
+++ /dev/null
@@ -1,388 +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 */
-
-/* Functions to handle typelib */
-
-#include "mysys_priv.h"
-#include <m_string.h>
-#include <m_ctype.h>
-
-
-#define is_field_separator(X) ((X) == ',' || (X) == '=')
-
-int find_type_or_exit(const char *x, TYPELIB *typelib, const char *option)
-{
- int res;
- const char **ptr;
-
- if ((res= find_type((char *) x, typelib, 2)) <= 0)
- {
- ptr= typelib->type_names;
- if (!*x)
- fprintf(stderr, "No option given to %s\n", option);
- else
- fprintf(stderr, "Unknown option to %s: %s\n", option, x);
- fprintf(stderr, "Alternatives are: '%s'", *ptr);
- while (*++ptr)
- fprintf(stderr, ",'%s'", *ptr);
- fprintf(stderr, "\n");
- exit(1);
- }
- return res;
-}
-
-
-/**
- Search after a string in a list of strings. Endspace in x is not compared.
-
- @param x String to find
- @param lib TYPELIB (struct of pointer to values + count)
- @param full_name bitmap of what to do
- If & 1 accept only whole names
- If & 2 don't expand if half field
- If & 4 allow #number# as type
- If & 8 use ',' as string terminator
-
- @note
- If part, uniq field is found and full_name == 0 then x is expanded
- to full field.
-
- @retval
- -1 Too many matching values
- @retval
- 0 No matching value
- @retval
- >0 Offset+1 in typelib for matched string
-*/
-
-
-int find_type(char *x, const TYPELIB *typelib, uint full_name)
-{
- int find,pos;
- int UNINIT_VAR(findpos); /* guarded by find */
- reg1 char * i;
- reg2 const char *j;
- DBUG_ENTER("find_type");
- DBUG_PRINT("enter",("x: '%s' lib: 0x%lx", x, (long) typelib));
-
- if (!typelib->count)
- {
- DBUG_PRINT("exit",("no count"));
- DBUG_RETURN(0);
- }
- find=0;
- for (pos=0 ; (j=typelib->type_names[pos]) ; pos++)
- {
- for (i=x ;
- *i && (!(full_name & 8) || !is_field_separator(*i)) &&
- my_toupper(&my_charset_latin1,*i) ==
- my_toupper(&my_charset_latin1,*j) ; i++, j++) ;
- if (! *j)
- {
- while (*i == ' ')
- i++; /* skip_end_space */
- if (! *i || ((full_name & 8) && is_field_separator(*i)))
- DBUG_RETURN(pos+1);
- }
- if ((!*i && (!(full_name & 8) || !is_field_separator(*i))) &&
- (!*j || !(full_name & 1)))
- {
- find++;
- findpos=pos;
- }
- }
- if (find == 0 && (full_name & 4) && x[0] == '#' && strend(x)[-1] == '#' &&
- (findpos=atoi(x+1)-1) >= 0 && (uint) findpos < typelib->count)
- find=1;
- else if (find == 0 || ! x[0])
- {
- DBUG_PRINT("exit",("Couldn't find type"));
- DBUG_RETURN(0);
- }
- else if (find != 1 || (full_name & 1))
- {
- DBUG_PRINT("exit",("Too many possybilities"));
- DBUG_RETURN(-1);
- }
- if (!(full_name & 2))
- (void) strmov(x,typelib->type_names[findpos]);
- DBUG_RETURN(findpos+1);
-} /* find_type */
-
-
-/**
- Get name of type nr
-
- @note
- first type is 1, 0 = empty field
-*/
-
-void make_type(register char * to, register uint nr,
- register TYPELIB *typelib)
-{
- DBUG_ENTER("make_type");
- if (!nr)
- to[0]=0;
- else
- (void) strmov(to,get_type(typelib,nr-1));
- DBUG_VOID_RETURN;
-} /* make_type */
-
-
-/**
- Get type
-
- @note
- first type is 0
-*/
-
-const char *get_type(TYPELIB *typelib, uint nr)
-{
- if (nr < (uint) typelib->count && typelib->type_names)
- return(typelib->type_names[nr]);
- return "?";
-}
-
-
-/**
- Create an integer value to represent the supplied comma-seperated
- string where each string in the TYPELIB denotes a bit position.
-
- @param x string to decompose
- @param lib TYPELIB (struct of pointer to values + count)
- @param err index (not char position) of string element which was not
- found or 0 if there was no error
-
- @retval
- a integer representation of the supplied string
-*/
-
-my_ulonglong find_typeset(char *x, TYPELIB *lib, int *err)
-{
- my_ulonglong result;
- int find;
- char *i;
- DBUG_ENTER("find_set");
- DBUG_PRINT("enter",("x: '%s' lib: 0x%lx", x, (long) lib));
-
- if (!lib->count)
- {
- DBUG_PRINT("exit",("no count"));
- DBUG_RETURN(0);
- }
- result= 0;
- *err= 0;
- while (*x)
- {
- (*err)++;
- i= x;
- while (*x && !is_field_separator(*x))
- x++;
- if (x[0] && x[1]) /* skip separator if found */
- x++;
- if ((find= find_type(i, lib, 2 | 8) - 1) < 0)
- DBUG_RETURN(0);
- result|= (ULL(1) << find);
- }
- *err= 0;
- DBUG_RETURN(result);
-} /* find_set */
-
-
-/**
- Create a copy of a specified TYPELIB structure.
-
- @param root pointer to a MEM_ROOT object for allocations
- @param from pointer to a source TYPELIB structure
-
- @retval
- pointer to the new TYPELIB structure on successful copy
- @retval
- NULL otherwise
-*/
-
-TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from)
-{
- TYPELIB *to;
- uint i;
-
- if (!from)
- return NULL;
-
- if (!(to= (TYPELIB*) alloc_root(root, sizeof(TYPELIB))))
- return NULL;
-
- if (!(to->type_names= (const char **)
- alloc_root(root, (sizeof(char *) + sizeof(int)) * (from->count + 1))))
- return NULL;
- to->type_lengths= (unsigned int *)(to->type_names + from->count + 1);
- to->count= from->count;
- if (from->name)
- {
- if (!(to->name= strdup_root(root, from->name)))
- return NULL;
- }
- else
- to->name= NULL;
-
- for (i= 0; i < from->count; i++)
- {
- if (!(to->type_names[i]= strmake_root(root, from->type_names[i],
- from->type_lengths[i])))
- return NULL;
- to->type_lengths[i]= from->type_lengths[i];
- }
- to->type_names[to->count]= NULL;
- to->type_lengths[to->count]= 0;
-
- return to;
-}
-
-
-static const char *on_off_default_names[]= { "off","on","default", 0};
-static TYPELIB on_off_default_typelib= {array_elements(on_off_default_names)-1,
- "", on_off_default_names, 0};
-
-/**
- Parse a TYPELIB name from the buffer
-
- @param lib Set of names to scan for.
- @param strpos INOUT Start of the buffer (updated to point to the next
- character after the name)
- @param end End of the buffer
-
- @note
- The buffer is assumed to contain one of the names specified in the TYPELIB,
- followed by comma, '=', or end of the buffer.
-
- @retval
- 0 No matching name
- @retval
- >0 Offset+1 in typelib for matched name
-*/
-
-static uint parse_name(const TYPELIB *lib, const char **strpos, const char *end)
-{
- const char *pos= *strpos;
- uint find= find_type((char*)pos, lib, 8);
- for (; pos != end && *pos != '=' && *pos !=',' ; pos++);
- *strpos= pos;
- return find;
-}
-
-/**
- Parse and apply a set of flag assingments
-
- @param lib Flag names
- @param default_name Number of "default" in the typelib
- @param cur_set Current set of flags (start from this state)
- @param default_set Default set of flags (use this for assign-default
- keyword and flag=default assignments)
- @param str String to be parsed
- @param length Length of the string
- @param err_pos OUT If error, set to point to start of wrong set string
- NULL on success
- @param err_len OUT If error, set to the length of wrong set string
-
- @details
- Parse a set of flag assignments, that is, parse a string in form:
-
- param_name1=value1,param_name2=value2,...
-
- where the names are specified in the TYPELIB, and each value can be
- either 'on','off', or 'default'. Setting the same name twice is not
- allowed.
-
- Besides param=val assignments, we support the "default" keyword (keyword
- #default_name in the typelib). It can be used one time, if specified it
- causes us to build the new set over the default_set rather than cur_set
- value.
-
- @note
- it's not charset aware
-
- @retval
- Parsed set value if (*errpos == NULL), otherwise undefined
-*/
-
-my_ulonglong find_set_from_flags(const TYPELIB *lib, uint default_name,
- my_ulonglong cur_set, my_ulonglong default_set,
- const char *str, uint length,
- char **err_pos, uint *err_len)
-{
- const char *end= str + length;
- my_ulonglong flags_to_set= 0, flags_to_clear= 0, res;
- my_bool set_defaults= 0;
-
- *err_pos= 0; /* No error yet */
- if (str != end)
- {
- const char *start= str;
- for (;;)
- {
- const char *pos= start;
- uint flag_no, value;
-
- if (!(flag_no= parse_name(lib, &pos, end)))
- goto err;
-
- if (flag_no == default_name)
- {
- /* Using 'default' twice isn't allowed. */
- if (set_defaults)
- goto err;
- set_defaults= TRUE;
- }
- else
- {
- my_ulonglong bit= (1ULL << (flag_no - 1));
- /* parse the '=on|off|default' */
- if ((flags_to_clear | flags_to_set) & bit ||
- pos >= end || *pos++ != '=' ||
- !(value= parse_name(&on_off_default_typelib, &pos, end)))
- goto err;
-
- if (value == 1) /* this is '=off' */
- flags_to_clear|= bit;
- else if (value == 2) /* this is '=on' */
- flags_to_set|= bit;
- else /* this is '=default' */
- {
- if (default_set & bit)
- flags_to_set|= bit;
- else
- flags_to_clear|= bit;
- }
- }
- if (pos >= end)
- break;
-
- if (*pos++ != ',')
- goto err;
-
- start=pos;
- continue;
- err:
- *err_pos= (char*)start;
- *err_len= end - start;
- break;
- }
- }
- res= set_defaults? default_set : cur_set;
- res|= flags_to_set;
- res&= ~flags_to_clear;
- return res;
-}
-