Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
654b3e60
Commit
654b3e60
authored
Oct 04, 2010
by
Vasil Dimov
Browse files
Options
Browse Files
Download
Plain Diff
Merge mysql-5.5-bugteam -> mysql-5.5-innodb
parents
18520902
f3f1db2a
Changes
12
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
631 additions
and
131 deletions
+631
-131
client/mysqltest.cc
client/mysqltest.cc
+90
-23
include/my_pthread.h
include/my_pthread.h
+67
-13
mysql-test/lib/mtr_report.pm
mysql-test/lib/mtr_report.pm
+8
-3
mysql-test/mysql-test-run.pl
mysql-test/mysql-test-run.pl
+23
-7
mysql-test/r/mysqltest.result
mysql-test/r/mysqltest.result
+18
-10
mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test
mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test
+2
-2
mysql-test/suite/sys_vars/t/div_precision_increment_func.test
...l-test/suite/sys_vars/t/div_precision_increment_func.test
+1
-1
mysql-test/suite/sys_vars/t/secure_file_priv.test
mysql-test/suite/sys_vars/t/secure_file_priv.test
+1
-1
mysql-test/t/mysqltest.test
mysql-test/t/mysqltest.test
+58
-27
mysys/my_wincond.c
mysys/my_wincond.c
+190
-42
mysys/my_winthread.c
mysys/my_winthread.c
+13
-2
mysys/thr_rwlock.c
mysys/thr_rwlock.c
+160
-0
No files found.
client/mysqltest.cc
View file @
654b3e60
This diff is collapsed.
Click to expand it.
include/my_pthread.h
View file @
654b3e60
...
...
@@ -48,19 +48,30 @@ typedef struct st_pthread_link {
struct
st_pthread_link
*
next
;
}
pthread_link
;
typedef
struct
{
/**
Implementation of Windows condition variables.
We use native conditions on Vista and later, and fallback to own
implementation on earlier OS version.
*/
typedef
union
{
/* Native condition (used on Vista and later) */
CONDITION_VARIABLE
native_cond
;
/* Own implementation (used on XP) */
struct
{
uint32
waiting
;
CRITICAL_SECTION
lock_waiting
;
enum
{
enum
{
SIGNAL
=
0
,
BROADCAST
=
1
,
MAX_EVENTS
=
2
}
EVENTS
;
HANDLE
events
[
MAX_EVENTS
];
HANDLE
broadcast_block_event
;
};
}
pthread_cond_t
;
...
...
@@ -679,6 +690,47 @@ extern int rw_pr_destroy(rw_pr_lock_t *);
#ifdef NEED_MY_RW_LOCK
#ifdef _WIN32
/**
Implementation of Windows rwlock.
We use native (slim) rwlocks on Win7 and later, and fallback to portable
implementation on earlier Windows.
slim rwlock are also available on Vista/WS2008, but we do not use it
("trylock" APIs are missing on Vista)
*/
typedef
union
{
/* Native rwlock (is_srwlock == TRUE) */
struct
{
SRWLOCK
srwlock
;
/* native reader writer lock */
BOOL
have_exclusive_srwlock
;
/* used for unlock */
};
/*
Portable implementation (is_srwlock == FALSE)
Fields are identical with Unix my_rw_lock_t fields.
*/
struct
{
pthread_mutex_t
lock
;
/* lock for structure */
pthread_cond_t
readers
;
/* waiting readers */
pthread_cond_t
writers
;
/* waiting writers */
int
state
;
/* -1:writer,0:free,>0:readers */
int
waiters
;
/* number of waiting writers */
#ifdef SAFE_MUTEX
pthread_t
write_thread
;
#endif
};
}
my_rw_lock_t
;
#else
/* _WIN32 */
/*
On systems which don't support native read/write locks we have
to use own implementation.
...
...
@@ -694,6 +746,8 @@ typedef struct st_my_rw_lock_t {
#endif
}
my_rw_lock_t
;
#endif
/*! _WIN32 */
extern
int
my_rw_init
(
my_rw_lock_t
*
);
extern
int
my_rw_destroy
(
my_rw_lock_t
*
);
extern
int
my_rw_rdlock
(
my_rw_lock_t
*
);
...
...
mysql-test/lib/mtr_report.pm
View file @
654b3e60
...
...
@@ -229,7 +229,8 @@ sub mtr_report_stats ($$;$) {
# Find out how we where doing
# ----------------------------------------------------------------------
my
$tot_skiped
=
0
;
my
$tot_skipped
=
0
;
my
$tot_skipdetect
=
0
;
my
$tot_passed
=
0
;
my
$tot_failed
=
0
;
my
$tot_tests
=
0
;
...
...
@@ -246,8 +247,9 @@ sub mtr_report_stats ($$;$) {
}
elsif
(
$tinfo
->
{'
result
'}
eq
'
MTR_RES_SKIPPED
'
)
{
# Test was skipped
$tot_skiped
++
;
# Test was skipped (disabled not counted)
$tot_skipped
++
unless
$tinfo
->
{'
disable
'};
$tot_skipdetect
++
if
$tinfo
->
{'
skip_detected_by_test
'};
}
elsif
(
$tinfo
->
{'
result
'}
eq
'
MTR_RES_PASSED
'
)
{
...
...
@@ -376,6 +378,9 @@ sub mtr_report_stats ($$;$) {
print
"
All
$tot_tests
tests were successful.
\n\n
";
}
print
"
$tot_skipped
tests were skipped,
"
.
"
$tot_skipdetect
by the test itself.
\n\n
"
if
$tot_skipped
;
if
(
$tot_failed
!=
0
||
$found_problems
)
{
mtr_error
("
there were failing test cases
")
unless
$dont_error
;
...
...
mysql-test/mysql-test-run.pl
View file @
654b3e60
...
...
@@ -126,13 +126,25 @@ my $path_vardir_trace; # unix formatted opt_vardir for trace files
my
$opt_tmpdir
;
# Path to use for tmp/ dir
my
$opt_tmpdir_pid
;
my
$opt_start
;
my
$opt_start_dirty
;
my
$opt_start_exit
;
my
$start_only
;
END
{
if
(
defined
$opt_tmpdir_pid
and
$opt_tmpdir_pid
==
$$
)
{
if
(
!
$opt_start_exit
)
{
# Remove the tempdir this process has created
mtr_verbose
("
Removing tmpdir '
$opt_tmpdir
");
mtr_verbose
("
Removing tmpdir
$opt_tmpdir
");
rmtree
(
$opt_tmpdir
);
}
else
{
mtr_warning
("
tmpdir
$opt_tmpdir
should be removed after the server has finished
");
}
}
}
sub
env_or_val
($$)
{
defined
$ENV
{
$_
[
0
]}
?
$ENV
{
$_
[
0
]}
:
$_
[
1
]
}
...
...
@@ -234,10 +246,6 @@ my $opt_start_timeout = $ENV{MTR_START_TIMEOUT} || 180; # seconds
sub
suite_timeout
{
return
$opt_suite_timeout
*
60
;
};
sub
check_timeout
{
return
$opt_testcase_timeout
*
6
;
};
my
$opt_start
;
my
$opt_start_dirty
;
my
$opt_start_exit
;
my
$start_only
;
my
$opt_wait_all
;
my
$opt_user_args
;
my
$opt_repeat
=
1
;
...
...
@@ -2186,6 +2194,11 @@ sub environment_setup {
# to detect that valgrind is being used from test cases
$ENV
{'
VALGRIND_TEST
'}
=
$opt_valgrind
;
# Add dir of this perl to aid mysqltest in finding perl
my
$perldir
=
dirname
(
$^X
);
my
$pathsep
=
"
:
";
$pathsep
=
"
;
"
if
IS_WINDOWS
&&
!
IS_CYGWIN
;
$ENV
{'
PATH
'}
=
"
$ENV
{'PATH'}
"
.
$pathsep
.
$perldir
;
}
...
...
@@ -3658,6 +3671,9 @@ sub run_testcase ($) {
# Try to get reason from test log file
find_testcase_skipped_reason
(
$tinfo
);
mtr_report_test_skipped
(
$tinfo
);
# Restart if skipped due to missing perl, it may have had side effects
stop_all_servers
(
$opt_shutdown_timeout
)
if
(
$tinfo
->
{'
comment
'}
=~
/^perl not found/
);
}
elsif
(
$res
==
65
)
{
...
...
mysql-test/r/mysqltest.result
View file @
654b3e60
...
...
@@ -177,6 +177,9 @@ mysqltest: At line 1: End of line junk detected: "disconnect default # comment
"
mysqltest: At line 1: Extra delimiter ";" found
mysqltest: At line 1: Extra delimiter ";" found
mysqltest: At line 1: Spurious text after `query` expression
mysqltest: At line 1: Spurious text after `query` expression
mysqltest: At line 2: Spurious text after `query` expression
mysqltest: At line 1: Missing argument(s) to 'error'
mysqltest: At line 1: Missing argument(s) to 'error'
mysqltest: At line 1: The sqlstate definition must start with an uppercase S
...
...
@@ -366,23 +369,24 @@ mysqltest: At line 1: Missing required argument 'sleep_delay' to command 'real_s
mysqltest: At line 1: Invalid argument to sleep "abc"
mysqltest: At line 1: Invalid argument to real_sleep "abc"
1
2
101
hej
1
-99
mysqltest: At line 1: Missing argument to inc
mysqltest: At line 1: The argument to inc must be a variable (start with $)
mysqltest: At line 1: Cannot perform inc/dec on a non-numeric value
mysqltest: At line 1: End of line junk detected: "1000"
4
4
mysqltest: At line 1: Cannot perform inc/dec on a non-numeric value
mysqltest: At line 1: Cannot perform inc/dec on a non-numeric value
-96
-96
-1
-2
99
hej
-1
mysqltest: At line 1: Missing argument to dec
mysqltest: At line 1: The argument to dec must be a variable (start with $)
mysqltest: At line 1: Cannot perform inc/dec on a non-numeric value
mysqltest: At line 1: End of line junk detected: "1000"
mysqltest: At line 1: Cannot perform inc/dec on a non-numeric value
mysqltest: At line 1: Cannot perform inc/dec on a non-numeric value
mysqltest: At line 1: Missing arguments to system, nothing to do!
mysqltest: At line 1: Missing arguments to system, nothing to do!
system command 'NonExistsinfComamdn 2> /dev/null' failed
...
...
@@ -449,12 +453,16 @@ mysqltest: At line 1: Missing required argument 'host' to command 'connect'
mysqltest: At line 1: query 'connect con2,localhost,root,,illegal_db' failed: 1049: Unknown database 'illegal_db'
mysqltest: At line 1: Illegal argument for port: 'illegal_port'
mysqltest: At line 1: Illegal option to connect: SMTP
OK
mysqltest: The test didn't produce any output
200 connects succeeded
mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 3: connection 'test_con1' not found in connection pool
mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 2: Connection test_con1 already exists
show tables;
ERROR 3D000: No database selected
connect con1,localhost,root,,;
connection default;
connection con1;
disconnect con1;
connection default;
Output from mysqltest-x.inc
Output from mysqltest-x.inc
Output from mysqltest-x.inc
...
...
mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test
View file @
654b3e60
...
...
@@ -205,7 +205,7 @@ DROP TABLE `t1`;
--
echo
===
Using
mysqlbinlog
to
detect
failure
.
Before
the
patch
mysqlbinlog
would
find
a
corrupted
event
,
thence
would
fail
.
--
let
$MYSQLD_DATADIR
=
`SELECT @@datadir`
;
--
let
$MYSQLD_DATADIR
=
`SELECT @@datadir`
--
exec
$MYSQL_BINLOG
$MYSQLD_DATADIR
/
master
-
bin
.
000001
>
$MYSQLTEST_VARDIR
/
tmp
/
mysqlbinlog_bug42749
.
binlog
--
remove_file
$MYSQLTEST_VARDIR
/
tmp
/
mysqlbinlog_bug42749
.
binlog
...
...
@@ -330,7 +330,7 @@ while($ntables)
--
echo
### assertion: check that binlog is not corrupt. Using mysqlbinlog to
--
echo
### detect failure. Before the patch mysqlbinlog would find
--
echo
### a corrupted event, thence would fail.
--
let
$MYSQLD_DATADIR
=
`SELECT @@datadir`
;
--
let
$MYSQLD_DATADIR
=
`SELECT @@datadir`
--
exec
$MYSQL_BINLOG
-
v
--
hex
$MYSQLD_DATADIR
/
master
-
bin
.
000001
>
$MYSQLTEST_VARDIR
/
tmp
/
mysqlbinlog_bug50018
.
binlog
## clean up
...
...
mysql-test/suite/sys_vars/t/div_precision_increment_func.test
View file @
654b3e60
...
...
@@ -19,7 +19,7 @@
# #
################################################################################
let
$save_div_precision_increment
=
`SELECT @@global.div_precision_increment`
let
$save_div_precision_increment
=
`SELECT @@global.div_precision_increment`
;
#SET @save_div_precision_increment = @@global.div_precision_increment;
...
...
mysql-test/suite/sys_vars/t/secure_file_priv.test
View file @
654b3e60
...
...
@@ -9,7 +9,7 @@ SHOW VARIABLES LIKE 'secure_file_priv';
# Doing this in a portable manner is difficult but we should be able to
# count on the depth of the directory hierarchy used. Three steps up from
# the datadir is the 'mysql_test' directory.
--
let
$PROTECTED_FILE
=
`SELECT concat(@@datadir,'/../../../bug50373.txt')`
;
--
let
$PROTECTED_FILE
=
`SELECT concat(@@datadir,'/../../../bug50373.txt')`
--
eval
SELECT
*
FROM
t1
INTO
OUTFILE
'$PROTECTED_FILE'
;
DELETE
FROM
t1
;
--
eval
LOAD
DATA
INFILE
'$PROTECTED_FILE'
INTO
TABLE
t1
;
...
...
mysql-test/t/mysqltest.test
View file @
654b3e60
...
...
@@ -494,6 +494,32 @@ remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql;
--
error
1
--
exec
echo
"--disable_query_log;"
|
$MYSQL_TEST
2
>&
1
#
# Extra text after ``
#
# Cannot use exec echo here as ` may or may not need to be escaped
--
write_file
$MYSQLTEST_VARDIR
/
tmp
/
mysqltest
.
sql
let
$x
=
`select 1`
BOO
;
EOF
--
error
1
--
exec
$MYSQL_TEST
<
$MYSQLTEST_VARDIR
/
tmp
/
mysqltest
.
sql
2
>&
1
remove_file
$MYSQLTEST_VARDIR
/
tmp
/
mysqltest
.
sql
;
--
write_file
$MYSQLTEST_VARDIR
/
tmp
/
mysqltest
.
sql
--
let
$x
=
`select 1`
;
EOF
--
error
1
--
exec
$MYSQL_TEST
<
$MYSQLTEST_VARDIR
/
tmp
/
mysqltest
.
sql
2
>&
1
remove_file
$MYSQLTEST_VARDIR
/
tmp
/
mysqltest
.
sql
;
--
write_file
$MYSQLTEST_VARDIR
/
tmp
/
mysqltest
.
sql
# Missing ; in next line should be detected and cause failure
let
$x
=
`select 1`
let
$x
=
2
;
echo
$x
;
EOF
--
error
1
--
exec
$MYSQL_TEST
<
$MYSQLTEST_VARDIR
/
tmp
/
mysqltest
.
sql
2
>&
1
remove_file
$MYSQLTEST_VARDIR
/
tmp
/
mysqltest
.
sql
;
# Allow trailing # comment
--
sleep
1
# Wait for insert delayed to be executed.
...
...
@@ -980,16 +1006,13 @@ EOF
# ----------------------------------------------------------------------------
# Test inc
# ----------------------------------------------------------------------------
inc
$i
;
echo
$i
;
let
$i
=
0
;
inc
$i
;
echo
$i
;
let
$i
=
100
;
inc
$i
;
echo
$i
;
let
$i
=
hej
;
echo
$i
;
let
$i
=
-
100
;
inc
$i
;
echo
$i
;
...
...
@@ -998,7 +1021,13 @@ echo $i;
--
error
1
--
exec
echo
"inc i;"
|
$MYSQL_TEST
2
>&
1
--
error
1
--
exec
echo
"inc
\$
i;"
|
$MYSQL_TEST
2
>&
1
--
error
1
--
exec
echo
"let
\$
i=100; inc
\$
i 1000; echo
\$
i;"
|
$MYSQL_TEST
2
>&
1
--
error
1
--
exec
echo
"let
\$
i=text; inc
\$
i; echo
\$
i;"
|
$MYSQL_TEST
2
>&
1
--
error
1
--
exec
echo
"let
\$
i=10cc; inc
\$
i; echo
\$
i;"
|
$MYSQL_TEST
2
>&
1
inc
$i
;
inc
$i
;
inc
$i
;
--
echo
$i
echo
$i
;
...
...
@@ -1008,25 +1037,25 @@ echo $i;
# Test dec
# ----------------------------------------------------------------------------
dec
$d
;
echo
$d
;
let
$d
=
0
;
dec
$d
;
echo
$d
;
let
$d
=
100
;
dec
$d
;
echo
$d
;
let
$d
=
hej
;
echo
$d
;
dec
$d
;
echo
$d
;
--
error
1
--
exec
echo
"dec;"
|
$MYSQL_TEST
2
>&
1
--
error
1
--
exec
echo
"dec i;"
|
$MYSQL_TEST
2
>&
1
--
error
1
--
exec
echo
"dec
\$
i;"
|
$MYSQL_TEST
2
>&
1
--
error
1
--
exec
echo
"let
\$
i=100; dec
\$
i 1000; echo
\$
i;"
|
$MYSQL_TEST
2
>&
1
--
error
1
--
exec
echo
"let
\$
i=text; dec
\$
i; echo
\$
i;"
|
$MYSQL_TEST
2
>&
1
--
error
1
--
exec
echo
"let
\$
i=10cc; dec
\$
i; echo
\$
i;"
|
$MYSQL_TEST
2
>&
1
# ----------------------------------------------------------------------------
...
...
@@ -1439,19 +1468,6 @@ eval select "$long_rep" as x;
--
error
1
--
exec
echo
"connect (con1,localhost,root,,,,,SMTP POP);"
|
$MYSQL_TEST
2
>&
1
# Repeat connect/disconnect
--
write_file
$MYSQLTEST_VARDIR
/
tmp
/
mysqltest
.
sql
let
$i
=
100
;
while
(
$i
)
{
connect
(
test_con1
,
localhost
,
root
,,);
disconnect
test_con1
;
dec
$i
;
}
EOF
--
exec
echo
"source
$MYSQLTEST_VARDIR
/tmp/mysqltest.sql; echo OK; exit;"
|
$MYSQL_TEST
2
>&
1
remove_file
$MYSQLTEST_VARDIR
/
tmp
/
mysqltest
.
sql
;
# Repeat connect/disconnect
--
write_file
$MYSQLTEST_VARDIR
/
tmp
/
mysqltest
.
sql
let
$i
=
200
;
...
...
@@ -1461,9 +1477,8 @@ while ($i)
disconnect
test_con1
;
dec
$i
;
}
echo
200
connects
succeeded
;
EOF
--
replace_result
$MYSQLTEST_VARDIR
MYSQLTEST_VARDIR
--
error
1
--
exec
echo
"source
$MYSQLTEST_VARDIR
/tmp/mysqltest.sql;"
|
$MYSQL_TEST
2
>&
1
remove_file
$MYSQLTEST_VARDIR
/
tmp
/
mysqltest
.
sql
;
...
...
@@ -1504,6 +1519,22 @@ show tables;
disconnect
con2
;
connection
default
;
# Test enable_connect_log
--
enable_connect_log
connect
(
con1
,
localhost
,
root
,,);
connection
default
;
connection
con1
;
--
disable_query_log
# These should not be logged
connect
(
con2
,
localhost
,
root
,,
*
NO
-
ONE
*
);
connection
con2
;
disconnect
con2
;
connection
con1
;
--
enable_query_log
disconnect
con1
;
connection
default
;
--
disable_connect_log
# ----------------------------------------------------------------------------
# Test mysqltest arguments
# ----------------------------------------------------------------------------
...
...
mysys/my_wincond.c
View file @
654b3e60
...
...
@@ -24,7 +24,108 @@
#include <process.h>
#include <sys/timeb.h>
int
pthread_cond_init
(
pthread_cond_t
*
cond
,
const
pthread_condattr_t
*
attr
)
/*
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
);
...
...
@@ -53,7 +154,8 @@ int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
return
0
;
}
int
pthread_cond_destroy
(
pthread_cond_t
*
cond
)
static
int
legacy_cond_destroy
(
pthread_cond_t
*
cond
)
{
DeleteCriticalSection
(
&
cond
->
lock_waiting
);
...
...
@@ -65,48 +167,13 @@ int pthread_cond_destroy(pthread_cond_t *cond)
}
int
pthread_cond_wait
(
pthread_cond_t
*
cond
,
pthread_mutex_t
*
mutex
)
{
return
pthread_cond_timedwait
(
cond
,
mutex
,
NULL
);
}
int
pthread_cond_timedwait
(
pthread_cond_t
*
cond
,
pthread_mutex_t
*
mutex
,
static
int
legacy_cond_timedwait
(
pthread_cond_t
*
cond
,
pthread_mutex_t
*
mutex
,
struct
timespec
*
abstime
)
{
int
result
;
long
timeout
;
union
ft64
now
;
if
(
abstime
!=
NULL
)
{
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
*/
timeout
=
(
long
)((
abstime
->
tv
.
i64
-
now
.
i64
)
/
10000
);
/* Don't allow the timeout to be negative */
if
(
timeout
<
0
)
timeout
=
0L
;
/*
Make sure the calucated timeout does not exceed original timeout
value which could cause "wait for ever" if system time changes
*/
if
(
timeout
>
abstime
->
max_timeout_msec
)
timeout
=
abstime
->
max_timeout_msec
;
}
else
{
/* No time specified; don't expire */
timeout
=
INFINITE
;
}
DWORD
timeout
;
timeout
=
get_milliseconds
(
abstime
);
/*
Block access if previous broadcast hasn't finished.
This is just for safety and should normally not
...
...
@@ -142,7 +209,7 @@ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
return
result
==
WAIT_TIMEOUT
?
ETIMEDOUT
:
0
;
}
int
pthread
_cond_signal
(
pthread_cond_t
*
cond
)
static
int
legacy
_cond_signal
(
pthread_cond_t
*
cond
)
{
EnterCriticalSection
(
&
cond
->
lock_waiting
);
...
...
@@ -155,7 +222,7 @@ int pthread_cond_signal(pthread_cond_t *cond)
}
int
pthread
_cond_broadcast
(
pthread_cond_t
*
cond
)
static
int
legacy
_cond_broadcast
(
pthread_cond_t
*
cond
)
{
EnterCriticalSection
(
&
cond
->
lock_waiting
);
/*
...
...
@@ -177,6 +244,87 @@ int pthread_cond_broadcast(pthread_cond_t *cond)
}
/*
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
;
...
...
mysys/my_winthread.c
View file @
654b3e60
...
...
@@ -155,8 +155,19 @@ int pthread_cancel(pthread_t thread)
int
my_pthread_once
(
my_pthread_once_t
*
once_control
,
void
(
*
init_routine
)(
void
))
{
LONG
state
=
InterlockedCompareExchange
(
once_control
,
MY_PTHREAD_ONCE_INPROGRESS
,
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
:
...
...
mysys/thr_rwlock.c
View file @
654b3e60
...
...
@@ -20,6 +20,119 @@
#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
...
...
@@ -63,6 +176,22 @@ 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
);
...
...
@@ -81,6 +210,10 @@ int my_rw_init(my_rw_lock_t *rwp)
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
);
...
...
@@ -91,6 +224,11 @@ int my_rw_destroy(my_rw_lock_t *rwp)
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 */
...
...
@@ -105,6 +243,12 @@ int my_rw_rdlock(my_rw_lock_t *rwp)
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 */
...
...
@@ -120,6 +264,11 @@ int my_rw_tryrdlock(my_rw_lock_t *rwp)
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 */
...
...
@@ -140,6 +289,12 @@ int my_rw_wrlock(my_rw_lock_t *rwp)
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 */
...
...
@@ -158,6 +313,11 @@ int my_rw_trywrlock(my_rw_lock_t *rwp)
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
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment