mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Merge kboortz@bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/home/kent/bk/tmp/mysql-5.0-build
This commit is contained in:
@ -557,10 +557,6 @@ SOURCE=.\my_windac.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\my_winsem.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\my_winthread.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -4323,49 +4323,6 @@
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="my_winsem.c">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Max|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="TLS_DEBUG|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="TLS|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="my_winthread.c">
|
||||
<FileConfiguration
|
||||
|
@ -538,10 +538,6 @@ SOURCE=.\my_wincond.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\my_winsem.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\my_winthread.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -778,8 +778,6 @@ AC_CHECK_FUNC(bind, , AC_CHECK_LIB(bind, bind))
|
||||
# Check if crypt() exists in libc or libcrypt, sets LIBS if needed
|
||||
AC_SEARCH_LIBS(crypt, crypt, AC_DEFINE(HAVE_CRYPT, 1, [crypt]))
|
||||
|
||||
# For sem_xxx functions on Solaris 2.6
|
||||
AC_CHECK_FUNC(sem_init, , AC_CHECK_LIB(posix4, sem_init))
|
||||
MYSQL_CHECK_ZLIB_WITH_COMPRESS
|
||||
|
||||
# For large pages support
|
||||
|
@ -21,7 +21,7 @@ HEADERS_ABI = mysql.h mysql_com.h mysql_time.h \
|
||||
my_list.h my_alloc.h typelib.h
|
||||
pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \
|
||||
my_xml.h mysql_embed.h \
|
||||
my_semaphore.h my_pthread.h my_no_pthread.h raid.h \
|
||||
my_pthread.h my_no_pthread.h raid.h \
|
||||
errmsg.h my_global.h my_net.h \
|
||||
my_getopt.h sslopt-longopts.h my_dir.h \
|
||||
sslopt-vars.h sslopt-case.h sql_common.h keycache.h \
|
||||
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Module: semaphore.h
|
||||
*
|
||||
* Purpose:
|
||||
* Semaphores aren't actually part of the PThreads standard.
|
||||
* They are defined by the POSIX Standard:
|
||||
*
|
||||
* POSIX 1003.1b-1993 (POSIX.1b)
|
||||
*
|
||||
* Pthreads-win32 - POSIX Threads Library for Win32
|
||||
* Copyright (C) 1998
|
||||
*
|
||||
* 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; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* This is hacked by Monty to be included in mysys library */
|
||||
|
||||
#ifndef _my_semaphore_h_
|
||||
#define _my_semaphore_h_
|
||||
|
||||
#ifdef THREAD
|
||||
|
||||
C_MODE_START
|
||||
#ifdef HAVE_SEMAPHORE_H
|
||||
#include <semaphore.h>
|
||||
#elif !defined(__bsdi__)
|
||||
#ifdef __WIN__
|
||||
typedef HANDLE sem_t;
|
||||
#else
|
||||
typedef struct {
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
uint count;
|
||||
} sem_t;
|
||||
#endif /* __WIN__ */
|
||||
|
||||
int sem_init(sem_t * sem, int pshared, unsigned int value);
|
||||
int sem_destroy(sem_t * sem);
|
||||
int sem_trywait(sem_t * sem);
|
||||
int sem_wait(sem_t * sem);
|
||||
int sem_post(sem_t * sem);
|
||||
int sem_post_multiple(sem_t * sem, unsigned int count);
|
||||
int sem_getvalue(sem_t * sem, unsigned int * sval);
|
||||
|
||||
#endif /* !__bsdi__ */
|
||||
|
||||
C_MODE_END
|
||||
|
||||
#endif /* THREAD */
|
||||
|
||||
#endif /* !_my_semaphore_h_ */
|
46
mysql-test/r/ndb_single_user.result
Normal file
46
mysql-test/r/ndb_single_user.result
Normal file
@ -0,0 +1,46 @@
|
||||
use test;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
|
||||
create table t1 (a int key, b int unique, c int) engine ndb;
|
||||
ERROR HY000: Can't create table './test/t1.frm' (errno: 155)
|
||||
create table t1 (a int key, b int unique, c int) engine ndb;
|
||||
insert into t1 values (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0),(6,6,0),(7,7,0),(8,8,0),(9,9,0),(10,10,0);
|
||||
create table t2 as select * from t1;
|
||||
select * from t1 where a = 1;
|
||||
a b c
|
||||
1 1 0
|
||||
select * from t1 where b = 4;
|
||||
a b c
|
||||
4 4 0
|
||||
select * from t1 where a > 4 order by a;
|
||||
a b c
|
||||
5 5 0
|
||||
6 6 0
|
||||
7 7 0
|
||||
8 8 0
|
||||
9 9 0
|
||||
10 10 0
|
||||
update t1 set b=102 where a = 2;
|
||||
update t1 set b=103 where b = 3;
|
||||
update t1 set b=b+100;
|
||||
update t1 set b=b+100 where a > 7;
|
||||
delete from t1;
|
||||
insert into t1 select * from t2;
|
||||
drop table t1;
|
||||
ERROR 42S02: Unknown table 't1'
|
||||
create index new_index on t1 (c);
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
insert into t1 values (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0),(6,6,0),(7,7,0),(8,8,0),(9,9,0),(10,10,0);
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
select * from t1 where a = 1;
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
select * from t1 where b = 4;
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
update t1 set b=102 where a = 2;
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
update t1 set b=103 where b = 3;
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
update t1 set b=b+100;
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
update t1 set b=b+100 where a > 7;
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
drop table t1;
|
@ -12,3 +12,4 @@
|
||||
|
||||
ndb_load : Bug#17233
|
||||
user_limits : Bug#23921 random failure of user_limits.test
|
||||
ndb_single_user : Bug#27021 Error codes in mysqld in single user mode varies
|
||||
|
84
mysql-test/t/ndb_single_user.test
Normal file
84
mysql-test/t/ndb_single_user.test
Normal file
@ -0,0 +1,84 @@
|
||||
-- source include/have_ndb.inc
|
||||
-- source include/have_multi_ndb.inc
|
||||
-- source include/ndb_default_cluster.inc
|
||||
-- source include/not_embedded.inc
|
||||
|
||||
--disable_warnings
|
||||
use test;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
|
||||
--enable_warnings
|
||||
|
||||
# operations allowed while cluster is in single user mode
|
||||
|
||||
--connection server1
|
||||
--let $node_id= `SHOW STATUS LIKE 'Ndb_cluster_node_id'`
|
||||
--disable_query_log
|
||||
--eval set @node_id= SUBSTRING('$node_id', 20)+0
|
||||
--enable_query_log
|
||||
--let $node_id= `SELECT @node_id`
|
||||
--exec $NDB_MGM --no-defaults --ndb-connectstring="localhost:$NDBCLUSTER_PORT" -e "enter single user mode $node_id" >> $NDB_TOOLS_OUTPUT
|
||||
--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults --ndb-connectstring="localhost:$NDBCLUSTER_PORT" --single-user >> $NDB_TOOLS_OUTPUT
|
||||
|
||||
# verify that we are indeed in single user mode
|
||||
--connection server2
|
||||
--error 1005
|
||||
create table t1 (a int key, b int unique, c int) engine ndb;
|
||||
|
||||
# test some sql on first mysqld
|
||||
--connection server1
|
||||
create table t1 (a int key, b int unique, c int) engine ndb;
|
||||
insert into t1 values (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0),(6,6,0),(7,7,0),(8,8,0),(9,9,0),(10,10,0);
|
||||
create table t2 as select * from t1;
|
||||
# read with pk
|
||||
select * from t1 where a = 1;
|
||||
# read with unique index
|
||||
select * from t1 where b = 4;
|
||||
# read with ordered index
|
||||
select * from t1 where a > 4 order by a;
|
||||
# update with pk
|
||||
update t1 set b=102 where a = 2;
|
||||
# update with unique index
|
||||
update t1 set b=103 where b = 3;
|
||||
# update with full table scan
|
||||
update t1 set b=b+100;
|
||||
# update with ordered insex scan
|
||||
update t1 set b=b+100 where a > 7;
|
||||
# delete with full table scan
|
||||
delete from t1;
|
||||
insert into t1 select * from t2;
|
||||
|
||||
# test some sql on other mysqld
|
||||
--connection server2
|
||||
--error 1051
|
||||
drop table t1;
|
||||
--error 1146
|
||||
#--error 1296
|
||||
create index new_index on t1 (c);
|
||||
--error 1146
|
||||
#--error 1296
|
||||
insert into t1 values (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0),(6,6,0),(7,7,0),(8,8,0),(9,9,0),(10,10,0);
|
||||
--error 1146
|
||||
#--error 1296
|
||||
select * from t1 where a = 1;
|
||||
--error 1146
|
||||
#--error 1296
|
||||
select * from t1 where b = 4;
|
||||
--error 1146
|
||||
#--error 1296
|
||||
update t1 set b=102 where a = 2;
|
||||
--error 1146
|
||||
#--error 1296
|
||||
update t1 set b=103 where b = 3;
|
||||
--error 1146
|
||||
#--error 1296
|
||||
update t1 set b=b+100;
|
||||
--error 1146
|
||||
#--error 1296
|
||||
update t1 set b=b+100 where a > 7;
|
||||
|
||||
--exec $NDB_MGM --no-defaults --ndb-connectstring="localhost:$NDBCLUSTER_PORT" -e "exit single user mode" >> $NDB_TOOLS_OUTPUT
|
||||
--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults >> $NDB_TOOLS_OUTPUT
|
||||
|
||||
# cleanup
|
||||
--connection server1
|
||||
drop table t1;
|
@ -39,7 +39,7 @@ ADD_LIBRARY(mysys array.c charset-def.c charset.c checksum.c default.c default_m
|
||||
my_mkdir.c my_mmap.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c
|
||||
my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_sleep.c
|
||||
my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c
|
||||
my_windac.c my_winsem.c my_winthread.c my_write.c ptr_cmp.c queues.c
|
||||
my_windac.c my_winthread.c my_write.c ptr_cmp.c queues.c
|
||||
rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c
|
||||
thr_rwlock.c tree.c typelib.c base64.c my_memmem.c
|
||||
my_getpagesize.c)
|
||||
|
@ -50,7 +50,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
|
||||
my_sync.c my_getopt.c my_mkdir.c \
|
||||
default_modify.c default.c \
|
||||
my_compress.c checksum.c raid.cc \
|
||||
my_net.c my_semaphore.c my_port.c my_sleep.c \
|
||||
my_net.c my_port.c my_sleep.c \
|
||||
charset.c charset-def.c my_bitmap.c my_bit.c md5.c \
|
||||
my_gethostbyname.c rijndael.c my_aes.c sha1.c \
|
||||
my_handler.c my_netware.c my_largepage.c \
|
||||
@ -58,7 +58,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
|
||||
my_windac.c my_access.c base64.c my_libwrap.c
|
||||
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
|
||||
thr_mutex.c thr_rwlock.c mf_soundex.c my_conio.c \
|
||||
my_wincond.c my_winsem.c my_winthread.c CMakeLists.txt
|
||||
my_wincond.c my_winthread.c CMakeLists.txt
|
||||
libmysys_a_LIBADD = @THREAD_LOBJECTS@
|
||||
# test_dir_DEPENDENCIES= $(LIBRARIES)
|
||||
# testhash_DEPENDENCIES= $(LIBRARIES)
|
||||
|
@ -1,103 +0,0 @@
|
||||
/* Copyright (C) 2002-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 */
|
||||
|
||||
/*
|
||||
Simple implementation of semaphores, needed to compile MySQL on systems
|
||||
that doesn't support semaphores.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include <my_semaphore.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if !defined(__WIN__) && !defined(HAVE_SEMAPHORE_H) && defined(THREAD)
|
||||
|
||||
int sem_init(sem_t * sem, int pshared, uint value)
|
||||
{
|
||||
sem->count=value;
|
||||
pthread_cond_init(&sem->cond, 0);
|
||||
pthread_mutex_init(&sem->mutex, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sem_destroy(sem_t * sem)
|
||||
{
|
||||
int err1,err2;
|
||||
err1=pthread_cond_destroy(&sem->cond);
|
||||
err2=pthread_mutex_destroy(&sem->mutex);
|
||||
if (err1 || err2)
|
||||
{
|
||||
errno=err1 ? err1 : err2;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sem_wait(sem_t * sem)
|
||||
{
|
||||
if ((errno=pthread_mutex_lock(&sem->mutex)))
|
||||
return -1;
|
||||
while (!sem->count)
|
||||
pthread_cond_wait(&sem->cond, &sem->mutex);
|
||||
if (errno)
|
||||
return -1;
|
||||
sem->count--; /* mutex is locked here */
|
||||
pthread_mutex_unlock(&sem->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sem_trywait(sem_t * sem)
|
||||
{
|
||||
if ((errno=pthread_mutex_lock(&sem->mutex)))
|
||||
return -1;
|
||||
if (sem->count)
|
||||
sem->count--;
|
||||
else
|
||||
errno=EAGAIN;
|
||||
pthread_mutex_unlock(&sem->mutex);
|
||||
return errno ? -1 : 0;
|
||||
}
|
||||
|
||||
|
||||
int sem_post(sem_t * sem)
|
||||
{
|
||||
if ((errno=pthread_mutex_lock(&sem->mutex)))
|
||||
return -1;
|
||||
sem->count++;
|
||||
pthread_mutex_unlock(&sem->mutex); /* does it really matter what to do */
|
||||
pthread_cond_signal(&sem->cond); /* first: x_unlock or x_signal ? */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sem_post_multiple(sem_t * sem, uint count)
|
||||
{
|
||||
if ((errno=pthread_mutex_lock(&sem->mutex)))
|
||||
return -1;
|
||||
sem->count+=count;
|
||||
pthread_mutex_unlock(&sem->mutex); /* does it really matter what to do */
|
||||
pthread_cond_broadcast(&sem->cond); /* first: x_unlock or x_broadcast ? */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sem_getvalue(sem_t * sem, uint *sval)
|
||||
{
|
||||
if ((errno=pthread_mutex_lock(&sem->mutex)))
|
||||
return -1;
|
||||
*sval=sem->count;
|
||||
pthread_mutex_unlock(&sem->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* !defined(__WIN__) && !defined(HAVE_SEMAPHORE_H) && defined(THREAD) */
|
@ -1,406 +0,0 @@
|
||||
/*
|
||||
* -------------------------------------------------------------
|
||||
*
|
||||
* Module: my_semaphore.c (Original: semaphore.c from pthreads library)
|
||||
*
|
||||
* Purpose:
|
||||
* Semaphores aren't actually part of the PThreads standard.
|
||||
* They are defined by the POSIX Standard:
|
||||
*
|
||||
* POSIX 1003.1b-1993 (POSIX.1b)
|
||||
*
|
||||
* -------------------------------------------------------------
|
||||
*
|
||||
* Pthreads-win32 - POSIX Threads Library for Win32
|
||||
* Copyright (C) 1998
|
||||
*
|
||||
* 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; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
NEED_SEM is not used in MySQL and should only be needed under
|
||||
Windows CE.
|
||||
|
||||
The big changes compared to the original version was to not allocate
|
||||
any additional memory in sem_init() but to instead store everthing
|
||||
we need in sem_t.
|
||||
|
||||
TODO:
|
||||
To get HAVE_CREATESEMAPHORE we have to define the struct
|
||||
in my_semaphore.h
|
||||
*/
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#ifdef __WIN__
|
||||
#include "my_semaphore.h"
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
DOCPUBLIC
|
||||
This function initializes an unnamed semaphore. the
|
||||
initial value of the semaphore is 'value'
|
||||
|
||||
PARAMETERS
|
||||
sem Pointer to an instance of sem_t
|
||||
|
||||
pshared If zero, this semaphore may only be shared between
|
||||
threads in the same process.
|
||||
If nonzero, the semaphore can be shared between
|
||||
processes
|
||||
|
||||
value Initial value of the semaphore counter
|
||||
|
||||
RESULTS
|
||||
0 Successfully created semaphore,
|
||||
-1 Failed, error in errno
|
||||
|
||||
ERRNO
|
||||
EINVAL 'sem' is not a valid semaphore,
|
||||
ENOSPC A required resource has been exhausted,
|
||||
ENOSYS Semaphores are not supported,
|
||||
EPERM The process lacks appropriate privilege
|
||||
|
||||
*/
|
||||
|
||||
int
|
||||
sem_init (sem_t *sem, int pshared, unsigned int value)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if (pshared != 0)
|
||||
{
|
||||
/*
|
||||
We don't support creating a semaphore that can be shared between
|
||||
processes
|
||||
*/
|
||||
result = EPERM;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef HAVE_CREATESEMAPHORE
|
||||
sem->value = value;
|
||||
sem->event = CreateEvent(NULL,
|
||||
FALSE, /* manual reset */
|
||||
FALSE, /* initial state */
|
||||
NULL);
|
||||
if (!sem->event)
|
||||
result = ENOSPC;
|
||||
else
|
||||
{
|
||||
if (value)
|
||||
SetEvent(sem->event);
|
||||
InitializeCriticalSection(&sem->sem_lock_cs);
|
||||
}
|
||||
#else /* HAVE_CREATESEMAPHORE */
|
||||
*sem = CreateSemaphore (NULL, /* Always NULL */
|
||||
value, /* Initial value */
|
||||
0x7FFFFFFFL, /* Maximum value */
|
||||
NULL); /* Name */
|
||||
if (!*sem)
|
||||
result = ENOSPC;
|
||||
#endif /* HAVE_CREATESEMAPHORE */
|
||||
}
|
||||
if (result != 0)
|
||||
{
|
||||
errno = result;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
} /* sem_init */
|
||||
|
||||
|
||||
/*
|
||||
DOCPUBLIC
|
||||
This function destroys an unnamed semaphore.
|
||||
|
||||
PARAMETERS
|
||||
sem Pointer to an instance of sem_t
|
||||
|
||||
RESULTS
|
||||
0 Successfully destroyed semaphore,
|
||||
-1 Failed, error in errno
|
||||
ERRNO
|
||||
EINVAL 'sem' is not a valid semaphore,
|
||||
ENOSYS Semaphores are not supported,
|
||||
EBUSY Threads (or processes) are currently blocked on 'sem'
|
||||
*/
|
||||
|
||||
int
|
||||
sem_destroy (sem_t * sem)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
#ifdef EXTRA_DEBUG
|
||||
if (sem == NULL || *sem == NULL)
|
||||
{
|
||||
errno=EINVAL;
|
||||
return;
|
||||
}
|
||||
#endif /* EXTRA_DEBUG */
|
||||
|
||||
#ifndef HAVE_CREATESEMAPHORE
|
||||
if (! CloseHandle(sem->event))
|
||||
result = EINVAL;
|
||||
else
|
||||
DeleteCriticalSection(&sem->sem_lock_cs);
|
||||
#else /* HAVE_CREATESEMAPHORE */
|
||||
if (!CloseHandle(*sem))
|
||||
result = EINVAL;
|
||||
#endif /* HAVE_CREATESEMAPHORE */
|
||||
if (result)
|
||||
{
|
||||
errno = result;
|
||||
return -1;
|
||||
}
|
||||
*sem=0; /* Safety */
|
||||
return 0;
|
||||
} /* sem_destroy */
|
||||
|
||||
|
||||
/*
|
||||
DOCPUBLIC
|
||||
This function tries to wait on a semaphore. If the
|
||||
semaphore value is greater than zero, it decreases
|
||||
its value by one. If the semaphore value is zero, then
|
||||
this function returns immediately with the error EAGAIN
|
||||
|
||||
PARAMETERS
|
||||
sem Pointer to an instance of sem_t
|
||||
|
||||
RESULTS
|
||||
0 Successfully decreased semaphore,
|
||||
-1 Failed, error in errno
|
||||
|
||||
ERRNO
|
||||
EAGAIN The semaphore was already locked,
|
||||
EINVAL 'sem' is not a valid semaphore,
|
||||
ENOSYS Semaphores are not supported,
|
||||
EINTR The function was interrupted by a signal,
|
||||
EDEADLK A deadlock condition was detected.
|
||||
*/
|
||||
|
||||
int
|
||||
sem_trywait(sem_t * sem)
|
||||
{
|
||||
#ifndef HAVE_CREATESEMAPHORE
|
||||
/* not yet implemented! */
|
||||
int errno = EINVAL;
|
||||
return -1;
|
||||
#else /* HAVE_CREATESEMAPHORE */
|
||||
#ifdef EXTRA_DEBUG
|
||||
if (sem == NULL || *sem == NULL)
|
||||
{
|
||||
errno=EINVAL;
|
||||
return -1;
|
||||
}
|
||||
#endif /* EXTRA_DEBUG */
|
||||
if (WaitForSingleObject (*sem, 0) == WAIT_TIMEOUT)
|
||||
{
|
||||
errno= EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
#endif /* HAVE_CREATESEMAPHORE */
|
||||
|
||||
} /* sem_trywait */
|
||||
|
||||
|
||||
#ifndef HAVE_CREATESEMAPHORE
|
||||
|
||||
static void
|
||||
ptw32_decrease_semaphore(sem_t * sem)
|
||||
{
|
||||
EnterCriticalSection(&sem->sem_lock_cs);
|
||||
DBUG_ASSERT(sem->value != 0);
|
||||
sem->value--;
|
||||
if (sem->value != 0)
|
||||
SetEvent(sem->event);
|
||||
LeaveCriticalSection(&sem->sem_lock_cs);
|
||||
}
|
||||
|
||||
static BOOL
|
||||
ptw32_increase_semaphore(sem_t * sem, unsigned int n)
|
||||
{
|
||||
BOOL result=FALSE;
|
||||
|
||||
EnterCriticalSection(&sem->sem_lock_cs);
|
||||
if (sem->value + n > sem->value)
|
||||
{
|
||||
sem->value += n;
|
||||
SetEvent(sem->event);
|
||||
result = TRUE;
|
||||
}
|
||||
LeaveCriticalSection(&sem->sem_lock_cs);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* HAVE_CREATESEMAPHORE */
|
||||
|
||||
|
||||
/*
|
||||
------------------------------------------------------
|
||||
DOCPUBLIC
|
||||
This function waits on a semaphore. If the
|
||||
semaphore value is greater than zero, it decreases
|
||||
its value by one. If the semaphore value is zero, then
|
||||
the calling thread (or process) is blocked until it can
|
||||
successfully decrease the value or until interrupted by
|
||||
a signal.
|
||||
|
||||
PARAMETERS
|
||||
sem Pointer to an instance of sem_t
|
||||
|
||||
RESULTS
|
||||
0 Successfully decreased semaphore,
|
||||
-1 Failed, error in errno
|
||||
|
||||
ERRNO
|
||||
EINVAL 'Sem' is not a valid semaphore,
|
||||
ENOSYS Semaphores are not supported,
|
||||
EINTR The function was interrupted by a signal,
|
||||
EDEADLK A deadlock condition was detected.
|
||||
*/
|
||||
|
||||
int
|
||||
sem_wait(sem_t *sem)
|
||||
{
|
||||
int result;
|
||||
|
||||
#ifdef EXTRA_DEBUG
|
||||
if (sem == NULL || *sem == NULL)
|
||||
{
|
||||
errno=EINVAL;
|
||||
return -1;
|
||||
}
|
||||
#endif /* EXTRA_DEBUG */
|
||||
|
||||
#ifndef HAVE_CREATESEMAPHORE
|
||||
result=WaitForSingleObject(sem->event, INFINITE);
|
||||
#else
|
||||
result=WaitForSingleObject(*sem, INFINITE);
|
||||
#endif
|
||||
if (result == WAIT_FAILED || result == WAIT_ABANDONED_0)
|
||||
result = EINVAL;
|
||||
else if (result == WAIT_TIMEOUT)
|
||||
result = ETIMEDOUT;
|
||||
else
|
||||
result=0;
|
||||
if (result)
|
||||
{
|
||||
errno = result;
|
||||
return -1;
|
||||
}
|
||||
#ifndef HAVE_CREATESEMAPHORE
|
||||
ptw32_decrease_semaphore(sem);
|
||||
#endif /* HAVE_CREATESEMAPHORE */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
------------------------------------------------------
|
||||
DOCPUBLIC
|
||||
This function posts a wakeup to a semaphore. If there
|
||||
are waiting threads (or processes), one is awakened;
|
||||
otherwise, the semaphore value is incremented by one.
|
||||
|
||||
PARAMETERS
|
||||
sem Pointer to an instance of sem_t
|
||||
|
||||
RESULTS
|
||||
0 Successfully posted semaphore,
|
||||
-1 Failed, error in errno
|
||||
|
||||
ERRNO
|
||||
EINVAL 'sem' is not a valid semaphore,
|
||||
ENOSYS Semaphores are not supported,
|
||||
|
||||
*/
|
||||
|
||||
int
|
||||
sem_post (sem_t * sem)
|
||||
{
|
||||
#ifdef EXTRA_DEBUG
|
||||
if (sem == NULL || *sem == NULL)
|
||||
{
|
||||
errno=EINVAL;
|
||||
return -1;
|
||||
}
|
||||
#endif /* EXTRA_DEBUG */
|
||||
|
||||
#ifndef HAVE_CREATESEMAPHORE
|
||||
if (! ptw32_increase_semaphore(sem, 1))
|
||||
#else /* HAVE_CREATESEMAPHORE */
|
||||
if (! ReleaseSemaphore(*sem, 1, 0))
|
||||
#endif /* HAVE_CREATESEMAPHORE */
|
||||
{
|
||||
errno=EINVAL;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
------------------------------------------------------
|
||||
DOCPUBLIC
|
||||
This function posts multiple wakeups to a semaphore. If there
|
||||
are waiting threads (or processes), n <= count are awakened;
|
||||
the semaphore value is incremented by count - n.
|
||||
|
||||
PARAMETERS
|
||||
sem Pointer to an instance of sem_t
|
||||
count Counter, must be greater than zero.
|
||||
|
||||
RESULTS
|
||||
0 Successfully posted semaphore,
|
||||
-1 Failed, error in errno
|
||||
|
||||
ERRNO
|
||||
EINVAL 'sem' is not a valid semaphore or count is less
|
||||
than or equal to zero.
|
||||
*/
|
||||
|
||||
int
|
||||
sem_post_multiple (sem_t * sem, unsigned int count)
|
||||
{
|
||||
#ifdef EXTRA_DEBUG
|
||||
if (sem == NULL || *sem == NULL || count <= 0)
|
||||
{
|
||||
errno=EINVAL;
|
||||
return -1;
|
||||
}
|
||||
#endif /* EXTRA_DEBUG */
|
||||
#ifndef HAVE_CREATESEMAPHORE
|
||||
if (! ptw32_increase_semaphore (sem, count))
|
||||
#else /* HAVE_CREATESEMAPHORE */
|
||||
if (! ReleaseSemaphore(*sem, count, 0))
|
||||
#endif /* HAVE_CREATESEMAPHORE */
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sem_getvalue (sem_t *sem, unsigned int *sval)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
} /* sem_getvalue */
|
||||
|
||||
#endif /* __WIN__ */
|
@ -2910,9 +2910,7 @@ Dbdict::execCREATE_TABLE_REQ(Signal* signal){
|
||||
break;
|
||||
}
|
||||
|
||||
if(getNodeState().getSingleUserMode() &&
|
||||
(refToNode(signal->getSendersBlockRef()) !=
|
||||
getNodeState().getSingleUserApi()))
|
||||
if (checkSingleUserMode(signal->getSendersBlockRef()))
|
||||
{
|
||||
jam();
|
||||
parseRecord.errorCode = CreateTableRef::SingleUser;
|
||||
@ -3081,9 +3079,7 @@ Dbdict::execALTER_TABLE_REQ(Signal* signal)
|
||||
return;
|
||||
}
|
||||
|
||||
if(getNodeState().getSingleUserMode() &&
|
||||
(refToNode(signal->getSendersBlockRef()) !=
|
||||
getNodeState().getSingleUserApi()))
|
||||
if (checkSingleUserMode(signal->getSendersBlockRef()))
|
||||
{
|
||||
jam();
|
||||
alterTableRef(signal, req, AlterTableRef::SingleUser);
|
||||
@ -5414,9 +5410,7 @@ Dbdict::execDROP_TABLE_REQ(Signal* signal){
|
||||
return;
|
||||
}
|
||||
|
||||
if(getNodeState().getSingleUserMode() &&
|
||||
(refToNode(signal->getSendersBlockRef()) !=
|
||||
getNodeState().getSingleUserApi()))
|
||||
if (checkSingleUserMode(signal->getSendersBlockRef()))
|
||||
{
|
||||
jam();
|
||||
dropTableRef(signal, req, DropTableRef::SingleUser);
|
||||
@ -6553,9 +6547,7 @@ Dbdict::execCREATE_INDX_REQ(Signal* signal)
|
||||
jam();
|
||||
tmperr = CreateIndxRef::Busy;
|
||||
}
|
||||
else if(getNodeState().getSingleUserMode() &&
|
||||
(refToNode(senderRef) !=
|
||||
getNodeState().getSingleUserApi()))
|
||||
else if (checkSingleUserMode(senderRef))
|
||||
{
|
||||
jam();
|
||||
tmperr = CreateIndxRef::SingleUser;
|
||||
@ -7130,9 +7122,7 @@ Dbdict::execDROP_INDX_REQ(Signal* signal)
|
||||
jam();
|
||||
tmperr = DropIndxRef::Busy;
|
||||
}
|
||||
else if(getNodeState().getSingleUserMode() &&
|
||||
(refToNode(senderRef) !=
|
||||
getNodeState().getSingleUserApi()))
|
||||
else if (checkSingleUserMode(senderRef))
|
||||
{
|
||||
jam();
|
||||
tmperr = DropIndxRef::SingleUser;
|
||||
@ -10574,4 +10564,20 @@ Dbdict::getMetaAttribute(MetaData::Attribute& attr, const MetaData::Table& table
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
return 1 if all of the below is true
|
||||
a) node in single user mode
|
||||
b) senderRef is not a db node
|
||||
c) senderRef nodeid is not the singleUserApi
|
||||
*/
|
||||
|
||||
int Dbdict::checkSingleUserMode(Uint32 senderRef)
|
||||
{
|
||||
Uint32 nodeId = refToNode(senderRef);
|
||||
return
|
||||
getNodeState().getSingleUserMode() &&
|
||||
(getNodeInfo(nodeId).m_type != NodeInfo::DB) &&
|
||||
(nodeId != getNodeState().getSingleUserApi());
|
||||
}
|
||||
|
||||
CArray<KeyDescriptor> g_key_descriptor_pool;
|
||||
|
@ -2003,6 +2003,8 @@ private:
|
||||
int getMetaTable(MetaData::Table& table, const char* tableName);
|
||||
int getMetaAttribute(MetaData::Attribute& attribute, const MetaData::Table& table, Uint32 attributeId);
|
||||
int getMetaAttribute(MetaData::Attribute& attribute, const MetaData::Table& table, const char* attributeName);
|
||||
|
||||
int checkSingleUserMode(Uint32 senderRef);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -800,6 +800,8 @@ NdbBlob::writeDataPrivate(const char* buf, Uint32 bytes)
|
||||
DBUG_RETURN(-1);
|
||||
Uint32 n = thePartSize - off;
|
||||
if (n > len) {
|
||||
/* If we are adding data at the end, fill rest of part. */
|
||||
if (pos + len >= theLength)
|
||||
memset(thePartBuf.data + off + len, theFillChar, n - len);
|
||||
n = len;
|
||||
}
|
||||
|
@ -880,6 +880,7 @@ NdbDictInterface::dictSignal(NdbApiSignal* signal,
|
||||
r = m_transporter->sendSignal(signal, aNodeId);
|
||||
}
|
||||
if(r != 0){
|
||||
m_error.code= 4007;
|
||||
m_transporter->unlock_mutex();
|
||||
continue;
|
||||
}
|
||||
@ -903,7 +904,10 @@ NdbDictInterface::dictSignal(NdbApiSignal* signal,
|
||||
* Handle error codes
|
||||
*/
|
||||
if(m_waiter.m_state == WAIT_NODE_FAILURE)
|
||||
{
|
||||
m_error.code = 4013;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(m_waiter.m_state == WST_WAIT_TIMEOUT)
|
||||
{
|
||||
|
@ -192,8 +192,7 @@ NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r)
|
||||
if (j > 0)
|
||||
out << " ";
|
||||
|
||||
switch(r.getType())
|
||||
{
|
||||
switch(r.getType()){
|
||||
case NdbDictionary::Column::Bigunsigned:
|
||||
out << r.u_64_value();
|
||||
break;
|
||||
@ -222,12 +221,12 @@ NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r)
|
||||
out << (int) r.char_value();
|
||||
break;
|
||||
case NdbDictionary::Column::Binary:
|
||||
ndbrecattr_print_string(out,"Binary",r.aRef(),r.arraySize());
|
||||
j = r.arraySize();
|
||||
ndbrecattr_print_string(out,"Binary", r.aRef(), j);
|
||||
break;
|
||||
case NdbDictionary::Column::Char:
|
||||
ndbrecattr_print_string(out,"Char",r.aRef(),r.arraySize());
|
||||
j = length;
|
||||
ndbrecattr_print_string(out,"Char", r.aRef(), r.arraySize());
|
||||
break;
|
||||
case NdbDictionary::Column::Varchar:
|
||||
{
|
||||
@ -374,8 +373,13 @@ NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r)
|
||||
j = length;
|
||||
}
|
||||
break;
|
||||
|
||||
case NdbDictionary::Column::Undefined:
|
||||
case NdbDictionary::Column::Mediumint:
|
||||
case NdbDictionary::Column::Mediumunsigned:
|
||||
case NdbDictionary::Column::Longvarbinary:
|
||||
unknown:
|
||||
default: /* no print functions for the rest, just print type */
|
||||
//default: /* no print functions for the rest, just print type */
|
||||
out << (int) r.getType();
|
||||
j = length;
|
||||
if (j > 1)
|
||||
|
@ -137,10 +137,12 @@ ErrorBundle ErrorCodes[] = {
|
||||
/**
|
||||
* Unknown result
|
||||
*/
|
||||
{ 4007, UR, "Send to ndbd node failed" },
|
||||
{ 4008, UR, "Receive from NDB failed" },
|
||||
{ 4009, UR, "Cluster Failure" },
|
||||
{ 4012, UR,
|
||||
"Request ndbd time-out, maybe due to high load or communication problems"},
|
||||
{ 4013, UR, "Request timed out in waiting for node failure"},
|
||||
{ 4024, UR,
|
||||
"Time-out, most likely caused by simple read or cluster failure" },
|
||||
|
||||
|
@ -138,6 +138,7 @@ printusage()
|
||||
<< " 2 readData / writeData" << endl
|
||||
<< "bug tests (no blob test)" << endl
|
||||
<< " -bug 4088 ndb api hang with mixed ops on index table" << endl
|
||||
<< " -bug 27018 middle partial part write clobbers rest of part" << endl
|
||||
<< " -bug nnnn delete + write gives 626" << endl
|
||||
<< " -bug nnnn acc crash on delete and long key" << endl
|
||||
;
|
||||
@ -1806,6 +1807,56 @@ bugtest_4088()
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bugtest_27018()
|
||||
{
|
||||
DBG("bug test 27018 - middle partial part write clobbers rest of part");
|
||||
|
||||
// insert rows
|
||||
calcTups(false);
|
||||
CHK(insertPk(false) == 0);
|
||||
// new trans
|
||||
for (unsigned k= 0; k < g_opt.m_rows; k++)
|
||||
{
|
||||
Tup& tup= g_tups[k];
|
||||
|
||||
CHK((g_con= g_ndb->startTransaction()) != 0);
|
||||
CHK((g_opr= g_con->getNdbOperation(g_opt.m_tname)) != 0);
|
||||
CHK(g_opr->updateTuple() == 0);
|
||||
CHK(g_opr->equal("PK1", tup.m_pk1) == 0);
|
||||
if (g_opt.m_pk2len != 0)
|
||||
CHK(g_opr->equal("PK2", tup.m_pk2) == 0);
|
||||
CHK(getBlobHandles(g_opr) == 0);
|
||||
CHK(g_con->execute(NoCommit) == 0);
|
||||
|
||||
/* Update one byte in random position. */
|
||||
Uint32 offset= urandom(tup.m_blob1.m_len);
|
||||
tup.m_blob1.m_buf[0]= 0xff ^ tup.m_blob1.m_val[offset];
|
||||
CHK(g_bh1->setPos(offset) == 0);
|
||||
CHK(g_bh1->writeData(&(tup.m_blob1.m_buf[0]), 1) == 0);
|
||||
CHK(g_con->execute(Commit) == 0);
|
||||
g_ndb->closeTransaction(g_con);
|
||||
|
||||
CHK((g_con= g_ndb->startTransaction()) != 0);
|
||||
CHK((g_opr= g_con->getNdbOperation(g_opt.m_tname)) != 0);
|
||||
CHK(g_opr->readTuple() == 0);
|
||||
CHK(g_opr->equal("PK1", tup.m_pk1) == 0);
|
||||
if (g_opt.m_pk2len != 0)
|
||||
CHK(g_opr->equal("PK2", tup.m_pk2) == 0);
|
||||
CHK(getBlobHandles(g_opr) == 0);
|
||||
|
||||
CHK(g_bh1->getValue(tup.m_blob1.m_buf, tup.m_blob1.m_len) == 0);
|
||||
CHK(g_con->execute(Commit) == 0);
|
||||
Uint64 len= ~0;
|
||||
CHK(g_bh1->getLength(len) == 0 && len == tup.m_blob1.m_len);
|
||||
tup.m_blob1.m_buf[offset]^= 0xff;
|
||||
CHK(memcmp(tup.m_blob1.m_buf, tup.m_blob1.m_val, tup.m_blob1.m_len) == 0);
|
||||
g_ndb->closeTransaction(g_con);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
bugtest_2222()
|
||||
{
|
||||
@ -1822,7 +1873,8 @@ static struct {
|
||||
int m_bug;
|
||||
int (*m_test)();
|
||||
} g_bugtest[] = {
|
||||
{ 4088, bugtest_4088 }
|
||||
{ 4088, bugtest_4088 },
|
||||
{ 27018, bugtest_27018 }
|
||||
};
|
||||
|
||||
NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535)
|
||||
|
@ -30,12 +30,14 @@ waitClusterStatus(const char* _addr, ndb_mgm_node_status _status,
|
||||
unsigned int _timeout);
|
||||
|
||||
enum ndb_waiter_options {
|
||||
OPT_WAIT_STATUS_NOT_STARTED = NDB_STD_OPTIONS_LAST
|
||||
OPT_WAIT_STATUS_NOT_STARTED = NDB_STD_OPTIONS_LAST,
|
||||
OPT_WAIT_STATUS_SINGLE_USER
|
||||
};
|
||||
NDB_STD_OPTS_VARS;
|
||||
|
||||
static int _no_contact = 0;
|
||||
static int _not_started = 0;
|
||||
static int _single_user = 0;
|
||||
static int _timeout = 120;
|
||||
|
||||
const char *load_default_groups[]= { "mysql_cluster",0 };
|
||||
@ -49,6 +51,10 @@ static struct my_option my_long_options[] =
|
||||
{ "not-started", OPT_WAIT_STATUS_NOT_STARTED, "Wait for cluster not started",
|
||||
(gptr*) &_not_started, (gptr*) &_not_started, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "single-user", OPT_WAIT_STATUS_SINGLE_USER,
|
||||
"Wait for cluster to enter single user mode",
|
||||
(gptr*) &_single_user, (gptr*) &_single_user, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
{ "timeout", 't', "Timeout to wait",
|
||||
(gptr*) &_timeout, (gptr*) &_timeout, 0,
|
||||
GET_INT, REQUIRED_ARG, 120, 0, 0, 0, 0, 0 },
|
||||
@ -90,6 +96,10 @@ int main(int argc, char** argv){
|
||||
{
|
||||
wait_status= NDB_MGM_NODE_STATUS_NOT_STARTED;
|
||||
}
|
||||
else if (_single_user)
|
||||
{
|
||||
wait_status= NDB_MGM_NODE_STATUS_SINGLEUSER;
|
||||
}
|
||||
else
|
||||
{
|
||||
wait_status= NDB_MGM_NODE_STATUS_STARTED;
|
||||
|
Reference in New Issue
Block a user