mirror of
https://github.com/isar/libmdbx.git
synced 2025-12-17 05:22:21 +08:00
Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f55e1ec5cc | ||
|
|
35f95e8ca2 | ||
|
|
ee7ebe438c | ||
|
|
f626acb398 | ||
|
|
eda424ff71 | ||
|
|
d5320d9252 | ||
|
|
3c684010e3 | ||
|
|
aa52cb395f | ||
|
|
73c7742db4 | ||
|
|
c3432c158e | ||
|
|
24d42c1583 | ||
|
|
40e3f735ab | ||
|
|
12174187e8 | ||
|
|
2770e193b6 | ||
|
|
83f1effff1 | ||
|
|
629637d95e | ||
|
|
06cb8b45b2 | ||
|
|
2d5cba61ed | ||
|
|
124c5a6751 | ||
|
|
3bae0723b7 | ||
|
|
5400ef6512 | ||
|
|
718f997502 | ||
|
|
c2f850b566 | ||
|
|
f93cca3d14 | ||
|
|
ecf214ca04 | ||
|
|
06e39e2728 | ||
|
|
2c643d5b53 | ||
|
|
3c4e9443ae | ||
|
|
d2bfb2e489 | ||
|
|
30a80ff07c | ||
|
|
582adda628 | ||
|
|
ae83982811 | ||
|
|
25ab7da33e | ||
|
|
96491db229 | ||
|
|
d520df6a13 | ||
|
|
cad9cea33b | ||
|
|
e229dbe9dc | ||
|
|
b47badb3ee | ||
|
|
f49741b4f8 | ||
|
|
80ccb31008 | ||
|
|
4dea5c2719 | ||
|
|
ded5269937 | ||
|
|
ae2875e248 | ||
|
|
aa64597e8b | ||
|
|
180c605cac | ||
|
|
23d2f0fbb5 | ||
|
|
9fae7f92d6 | ||
|
|
ace3d1bfa3 | ||
|
|
777d1db5c9 | ||
|
|
c9e3dc373b | ||
|
|
83f3d820f1 | ||
|
|
0f82db941b | ||
|
|
7a3c8743f3 | ||
|
|
03287b73a1 | ||
|
|
025cf0b00e |
9
Makefile
9
Makefile
@@ -82,13 +82,16 @@ clean:
|
||||
rm -rf $(TOOLS) mdbx_test @* *.[ao] *.[ls]o *~ tmp.db/* *.gcov *.log *.err src/*.o test/*.o
|
||||
|
||||
check: all
|
||||
rm -f $(TESTDB) $(TESTLOG) && (set -o pipefail; ./mdbx_test --pathname=$(TESTDB) --dont-cleanup-after basic | tee -a $(TESTLOG) | tail -n 42) && ./mdbx_chk -vvn $(TESTDB)
|
||||
rm -f $(TESTDB) $(TESTLOG) && (set -o pipefail; ./mdbx_test --pathname=$(TESTDB) --dont-cleanup-after basic | tee -a $(TESTLOG) | tail -n 42) \
|
||||
&& ./mdbx_chk -vvn $(TESTDB) && ./mdbx_chk -vvn $(TESTDB)-copy
|
||||
|
||||
check-singleprocess: all
|
||||
rm -f $(TESTDB) $(TESTLOG) && (set -o pipefail; ./mdbx_test --pathname=$(TESTDB) --dont-cleanup-after --hill | tee -a $(TESTLOG) | tail -n 42) && ./mdbx_chk -vvn $(TESTDB)
|
||||
rm -f $(TESTDB) $(TESTLOG) && (set -o pipefail; ./mdbx_test --pathname=$(TESTDB) --dont-cleanup-after --hill | tee -a $(TESTLOG) | tail -n 42) \
|
||||
&& ./mdbx_chk -vvn $(TESTDB) && ./mdbx_chk -vvn $(TESTDB)-copy
|
||||
|
||||
check-fault: all
|
||||
rm -f $(TESTDB) $(TESTLOG) && (set -o pipefail; ./mdbx_test --pathname=$(TESTDB) --inject-writefault=42 --dump-config --dont-cleanup-after basic | tee -a $(TESTLOG) | tail -n 42) && ./mdbx_chk -vvn $(TESTDB)
|
||||
rm -f $(TESTDB) $(TESTLOG) && (set -o pipefail; ./mdbx_test --pathname=$(TESTDB) --inject-writefault=42 --dump-config --dont-cleanup-after basic | tee -a $(TESTLOG) | tail -n 42) \
|
||||
&& ./mdbx_chk -vvn $(TESTDB) && ./mdbx_chk -vvn $(TESTDB)-copy
|
||||
|
||||
define core-rule
|
||||
$(patsubst %.c,%.o,$(1)): $(1) $(CORE_INC) mdbx.h Makefile
|
||||
|
||||
@@ -32,7 +32,12 @@ libmdbx
|
||||
6. [Asynchronous lazy data flushing](https://sites.fas.harvard.edu/~cs265/papers/kathuria-2008.pdf) to disk(s);
|
||||
7. etc...
|
||||
|
||||
Don't miss [Java Native Interface](https://github.com/castortech/mdbxjni) by [Castor Technologies](https://castortech.com/).
|
||||
Don't miss libmdbx for other runtimes.
|
||||
|
||||
| Runtime | GitHub | Author |
|
||||
| ------------- | ------------- | ------------- |
|
||||
| JVM | [mdbxjni](https://github.com/castortech/mdbxjni) | [Castor Technologies](https://castortech.com/) |
|
||||
| .NET | [mdbx.NET](https://github.com/wangjia184/mdbx.NET) | [Jerry Wang](https://github.com/wangjia184) |
|
||||
|
||||
-----
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@ environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
TOOLSET: v141
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
TOOLSET: v140
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
|
||||
TOOLSET: v120
|
||||
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
# TOOLSET: v140
|
||||
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
|
||||
# TOOLSET: v120
|
||||
|
||||
branches:
|
||||
except:
|
||||
|
||||
52
dll.vcxproj
52
dll.vcxproj
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
@@ -73,6 +73,7 @@
|
||||
<TargetName>mdbx</TargetName>
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<CustomBuildBeforeTargets>PreLinkEvent</CustomBuildBeforeTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
@@ -80,22 +81,25 @@
|
||||
<TargetName>mdbx</TargetName>
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<CustomBuildBeforeTargets>PreLinkEvent</CustomBuildBeforeTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<TargetName>mdbx</TargetName>
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<CustomBuildBeforeTargets>PreLinkEvent</CustomBuildBeforeTargets>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>mdbx</TargetName>
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||
<CustomBuildBeforeTargets>PreLinkEvent</CustomBuildBeforeTargets>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBMDBX_EXPORTS;%(PreprocessorDefinitions);MDBX_DEBUG=1</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBMDBX_EXPORTS;MDBX_BUILD_DLL;MDBX_AVOID_CRT;%(PreprocessorDefinitions);MDBX_DEBUG=1</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<WarningLevel>EnableAllWarnings</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
@@ -107,11 +111,18 @@
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<AdditionalDependencies>ntdll.lib;$(IntermediateOutputPath)mdbx_ntdll_extra.lib;kernel32.lib;advapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<CustomBuildStep>
|
||||
<Message>Generate fake-library mdbx_ntdll_extra.lib for $(PlatformTarget)</Message>
|
||||
<Outputs>$(IntermediateOutputPath)mdbx_ntdll_extra.lib</Outputs>
|
||||
<Inputs>$(ProjectDir)src/ntdll.def</Inputs>
|
||||
<Command>lib.exe /def:%(Inputs) /out:%(Outputs) /machine:$(PlatformTarget)</Command>
|
||||
</CustomBuildStep>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBMDBX_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBMDBX_EXPORTS;MDBX_BUILD_DLL;MDBX_AVOID_CRT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<WarningLevel>EnableAllWarnings</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
@@ -122,6 +133,9 @@
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<AssemblerOutput>All</AssemblerOutput>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
@@ -130,7 +144,15 @@
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
<AdditionalDependencies>ntdll.lib;$(IntermediateOutputPath)mdbx_ntdll_extra.lib;kernel32.lib;advapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||
</Link>
|
||||
<CustomBuildStep>
|
||||
<Message>Generate fake-library mdbx_ntdll_extra.lib for $(PlatformTarget)</Message>
|
||||
<Outputs>$(IntermediateOutputPath)mdbx_ntdll_extra.lib</Outputs>
|
||||
<Inputs>$(ProjectDir)src/ntdll.def</Inputs>
|
||||
<Command>lib.exe /def:%(Inputs) /out:%(Outputs) /machine:$(PlatformTarget)</Command>
|
||||
</CustomBuildStep>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
@@ -140,15 +162,24 @@
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>EnableAllWarnings</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;_USRDLL;LIBMDBX_EXPORTS;%(PreprocessorDefinitions);MDBX_DEBUG=1</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;_USRDLL;LIBMDBX_EXPORTS;MDBX_BUILD_DLL;MDBX_AVOID_CRT;%(PreprocessorDefinitions);MDBX_DEBUG=1</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<StringPooling>true</StringPooling>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>ntdll.lib;$(IntermediateOutputPath)mdbx_ntdll_extra.lib;kernel32.lib;advapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<CustomBuildStep>
|
||||
<Message>Generate fake-library mdbx_ntdll_extra.lib for $(PlatformTarget)</Message>
|
||||
<Outputs>$(IntermediateOutputPath)mdbx_ntdll_extra.lib</Outputs>
|
||||
<Inputs>$(ProjectDir)src/ntdll.def</Inputs>
|
||||
<Command>lib.exe /def:%(Inputs) /out:%(Outputs) /machine:$(PlatformTarget)</Command>
|
||||
</CustomBuildStep>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;LIBMDBX_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;LIBMDBX_EXPORTS;MDBX_BUILD_DLL;MDBX_AVOID_CRT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<StringPooling>true</StringPooling>
|
||||
<Optimization>Full</Optimization>
|
||||
@@ -158,10 +189,21 @@
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<WarningLevel>EnableAllWarnings</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<AssemblerOutput>All</AssemblerOutput>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
<AdditionalDependencies>ntdll.lib;$(IntermediateOutputPath)mdbx_ntdll_extra.lib;kernel32.lib;advapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||
</Link>
|
||||
<CustomBuildStep>
|
||||
<Message>Generate fake-library mdbx_ntdll_extra.lib for $(PlatformTarget)</Message>
|
||||
<Outputs>$(IntermediateOutputPath)mdbx_ntdll_extra.lib</Outputs>
|
||||
<Inputs>$(ProjectDir)src/ntdll.def</Inputs>
|
||||
<Command>lib.exe /def:%(Inputs) /out:%(Outputs) /machine:$(PlatformTarget)</Command>
|
||||
</CustomBuildStep>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\lck-windows.c" />
|
||||
|
||||
@@ -3,6 +3,7 @@ README-RU.md
|
||||
pcrf_test/CMakeLists.txt
|
||||
src/tools/CMakeLists.txt
|
||||
test/CMakeLists.txt
|
||||
test/copy.cc
|
||||
tutorial/CMakeLists.txt
|
||||
tutorial/sample-mdbx.c
|
||||
AUTHORS
|
||||
|
||||
2
mdbx.h
2
mdbx.h
@@ -207,6 +207,7 @@ extern LIBMDBX_API const mdbx_version_info mdbx_version;
|
||||
extern LIBMDBX_API const mdbx_build_info mdbx_build;
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#ifndef MDBX_BUILD_DLL
|
||||
|
||||
/* Dll initialization callback for ability to dynamically load MDBX DLL by
|
||||
* LoadLibrary() on Windows versions before Windows Vista. This function MUST be
|
||||
@@ -222,6 +223,7 @@ extern LIBMDBX_API const mdbx_build_info mdbx_build;
|
||||
void LIBMDBX_API NTAPI mdbx_dll_callback(PVOID module, DWORD reason,
|
||||
PVOID reserved);
|
||||
#endif /* MDBX_CONFIG_MANUAL_TLS_CALLBACK */
|
||||
#endif /* MDBX_BUILD_DLL */
|
||||
#endif /* Windows */
|
||||
|
||||
/* The name of the lock file in the DB environment */
|
||||
|
||||
2
mdbx.sln
2
mdbx.sln
@@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
|
||||
@@ -476,8 +476,10 @@ typedef struct MDBX_lockinfo {
|
||||
(uint16_t)(MDBX_LOCKINFO_WHOLE_SIZE + MDBX_CACHELINE_SIZE - 1))
|
||||
|
||||
#define MDBX_DATA_MAGIC ((MDBX_MAGIC << 8) + MDBX_DATA_VERSION)
|
||||
#define MDBX_DATA_MAGIC_DEVEL ((MDBX_MAGIC << 8) + 255)
|
||||
|
||||
#define MDBX_LOCK_MAGIC ((MDBX_MAGIC << 8) + MDBX_LOCK_VERSION)
|
||||
#define MDBX_LOCK_MAGIC_DEVEL ((MDBX_MAGIC << 8) + 255)
|
||||
|
||||
#ifndef MDBX_ASSUME_MALLOC_OVERHEAD
|
||||
#define MDBX_ASSUME_MALLOC_OVERHEAD (sizeof(void *) * 2u)
|
||||
@@ -868,6 +870,9 @@ void mdbx_panic(const char *fmt, ...)
|
||||
#endif /* NDEBUG */
|
||||
#endif /* MDBX_DEBUG */
|
||||
|
||||
LIBMDBX_API void mdbx_assert_fail(const MDBX_env *env, const char *msg,
|
||||
const char *func, int line);
|
||||
|
||||
#define mdbx_print(fmt, ...) \
|
||||
mdbx_debug_log(MDBX_DBG_PRINT, NULL, 0, fmt, ##__VA_ARGS__)
|
||||
|
||||
@@ -967,6 +972,9 @@ void mdbx_panic(const char *fmt, ...)
|
||||
/* assert(3) variant in transaction context */
|
||||
#define mdbx_tassert(txn, expr) mdbx_assert((txn)->mt_env, expr)
|
||||
|
||||
#undef assert
|
||||
#define assert(expr) mdbx_assert(NULL, expr)
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Internal prototypes */
|
||||
|
||||
|
||||
10
src/defs.h
10
src/defs.h
@@ -103,15 +103,15 @@
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __alwaysinline
|
||||
#ifndef __always_inline
|
||||
# if defined(__GNUC__) || __has_attribute(always_inline)
|
||||
# define __alwaysinline __inline __attribute__((always_inline))
|
||||
# define __always_inline __inline __attribute__((always_inline))
|
||||
# elif defined(_MSC_VER)
|
||||
# define __alwaysinline __forceinline
|
||||
# define __always_inline __forceinline
|
||||
# else
|
||||
# define __alwaysinline
|
||||
# define __always_inline
|
||||
# endif
|
||||
#endif /* __alwaysinline */
|
||||
#endif /* __always_inline */
|
||||
|
||||
#ifndef __noinline
|
||||
# if defined(__GNUC__) || __has_attribute(noinline)
|
||||
|
||||
@@ -126,7 +126,8 @@ int mdbx_rpid_check(MDBX_env *env, mdbx_pid_t pid) {
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static int mdbx_mutex_failed(MDBX_env *env, pthread_mutex_t *mutex, int rc);
|
||||
static int mdbx_mutex_failed(MDBX_env *env, pthread_mutex_t *mutex,
|
||||
const int rc);
|
||||
|
||||
int __cold mdbx_lck_init(MDBX_env *env) {
|
||||
pthread_mutexattr_t ma;
|
||||
@@ -297,9 +298,10 @@ int __cold mdbx_lck_seize(MDBX_env *env) {
|
||||
#endif
|
||||
|
||||
static int __cold mdbx_mutex_failed(MDBX_env *env, pthread_mutex_t *mutex,
|
||||
int rc) {
|
||||
const int err) {
|
||||
int rc = err;
|
||||
#if MDBX_USE_ROBUST
|
||||
if (rc == EOWNERDEAD) {
|
||||
if (err == EOWNERDEAD) {
|
||||
/* We own the mutex. Clean up after dead previous owner. */
|
||||
|
||||
int rlocked = (env->me_lck && mutex == &env->me_lck->mti_rmutex);
|
||||
@@ -331,10 +333,8 @@ static int __cold mdbx_mutex_failed(MDBX_env *env, pthread_mutex_t *mutex,
|
||||
}
|
||||
#endif /* MDBX_USE_ROBUST */
|
||||
|
||||
mdbx_error("mutex (un)lock failed, %s", mdbx_strerror(rc));
|
||||
if (rc != EDEADLK) {
|
||||
mdbx_error("mutex (un)lock failed, %s", mdbx_strerror(err));
|
||||
if (rc != EDEADLK)
|
||||
env->me_flags |= MDBX_FATAL_ERROR;
|
||||
rc = MDBX_PANIC;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -26,11 +26,29 @@
|
||||
|
||||
static void mdbx_winnt_import(void);
|
||||
|
||||
#ifdef MDBX_BUILD_DLL
|
||||
/* DEBUG/CHECKED builds still require MSVC's CRT for runtime checks.
|
||||
*
|
||||
* Therefore we don't define dll's entry point for debug/checked builds by MSVC.
|
||||
* In this case MSVC's will automatically use DllMainCRTStartup() from CRT
|
||||
* library, which also automatically call DllMain() from our mdbx.dll
|
||||
*
|
||||
* On the other side, for RELEASE builds
|
||||
* we explicitly define DllMain() as the entry point and don't linking with
|
||||
* any CRT libraries (IgnoreAllDefaultLibraries = Yes). */
|
||||
#if !defined(_MSC_VER) || defined(NDEBUG)
|
||||
#pragma comment(linker, "/ENTRY:DllMain")
|
||||
#endif
|
||||
|
||||
BOOL APIENTRY DllMain(HANDLE module, DWORD reason, LPVOID reserved)
|
||||
#else
|
||||
#if !MDBX_CONFIG_MANUAL_TLS_CALLBACK
|
||||
static
|
||||
#endif /* !MDBX_CONFIG_MANUAL_TLS_CALLBACK */
|
||||
void NTAPI
|
||||
mdbx_dll_callback(PVOID module, DWORD reason, PVOID reserved) {
|
||||
mdbx_dll_callback(PVOID module, DWORD reason, PVOID reserved)
|
||||
#endif /* MDBX_BUILD_DLL */
|
||||
{
|
||||
(void)reserved;
|
||||
switch (reason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
@@ -47,9 +65,12 @@ static
|
||||
mdbx_rthc_thread_dtor(module);
|
||||
break;
|
||||
}
|
||||
#ifdef MDBX_BUILD_DLL
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !MDBX_CONFIG_MANUAL_TLS_CALLBACK
|
||||
#if !defined(MDBX_BUILD_DLL) && !MDBX_CONFIG_MANUAL_TLS_CALLBACK
|
||||
/* *INDENT-OFF* */
|
||||
/* clang-format off */
|
||||
#if defined(_MSC_VER)
|
||||
@@ -87,7 +108,7 @@ static
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
/* clang-format on */
|
||||
#endif /* !MDBX_CONFIG_MANUAL_TLS_CALLBACK */
|
||||
#endif /* !defined(MDBX_BUILD_DLL) && !MDBX_CONFIG_MANUAL_TLS_CALLBACK */
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
@@ -191,12 +212,12 @@ static int suspend_and_append(mdbx_handle_array_t **array,
|
||||
const DWORD ThreadId) {
|
||||
const unsigned limit = (*array)->limit;
|
||||
if ((*array)->count == limit) {
|
||||
void *ptr = realloc((limit > ARRAY_LENGTH((*array)->handles))
|
||||
? *array
|
||||
: /* don't free initial array on the stack */ NULL,
|
||||
sizeof(mdbx_handle_array_t) +
|
||||
sizeof(HANDLE) *
|
||||
(limit * 2 - ARRAY_LENGTH((*array)->handles)));
|
||||
void *ptr = mdbx_realloc(
|
||||
(limit > ARRAY_LENGTH((*array)->handles))
|
||||
? *array
|
||||
: /* don't free initial array on the stack */ NULL,
|
||||
sizeof(mdbx_handle_array_t) +
|
||||
sizeof(HANDLE) * (limit * 2 - ARRAY_LENGTH((*array)->handles)));
|
||||
if (!ptr)
|
||||
return MDBX_ENOMEM;
|
||||
if (limit == ARRAY_LENGTH((*array)->handles))
|
||||
@@ -205,12 +226,19 @@ static int suspend_and_append(mdbx_handle_array_t **array,
|
||||
(*array)->limit = limit * 2;
|
||||
}
|
||||
|
||||
HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, ThreadId);
|
||||
HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME | THREAD_QUERY_INFORMATION,
|
||||
FALSE, ThreadId);
|
||||
if (hThread == NULL)
|
||||
return GetLastError();
|
||||
|
||||
if (SuspendThread(hThread) == -1) {
|
||||
int err = GetLastError();
|
||||
DWORD ExitCode;
|
||||
if (err == /* workaround for Win10 UCRT bug */ ERROR_ACCESS_DENIED ||
|
||||
!GetExitCodeThread(hThread, &ExitCode) || ExitCode != STILL_ACTIVE)
|
||||
err = MDBX_SUCCESS;
|
||||
CloseHandle(hThread);
|
||||
return GetLastError();
|
||||
return err;
|
||||
}
|
||||
|
||||
(*array)->handles[(*array)->count++] = hThread;
|
||||
@@ -295,9 +323,15 @@ int mdbx_suspend_threads_before_remap(MDBX_env *env,
|
||||
int mdbx_resume_threads_after_remap(mdbx_handle_array_t *array) {
|
||||
int rc = MDBX_SUCCESS;
|
||||
for (unsigned i = 0; i < array->count; ++i) {
|
||||
if (ResumeThread(array->handles[i]) == -1)
|
||||
rc = GetLastError();
|
||||
CloseHandle(array->handles[i]);
|
||||
const HANDLE hThread = array->handles[i];
|
||||
if (ResumeThread(hThread) == -1) {
|
||||
const int err = GetLastError();
|
||||
DWORD ExitCode;
|
||||
if (err != /* workaround for Win10 UCRT bug */ ERROR_ACCESS_DENIED &&
|
||||
GetExitCodeThread(hThread, &ExitCode) && ExitCode == STILL_ACTIVE)
|
||||
rc = err;
|
||||
}
|
||||
CloseHandle(hThread);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
664
src/mdbx.c
664
src/mdbx.c
File diff suppressed because it is too large
Load Diff
1244
src/ntdll.def
Normal file
1244
src/ntdll.def
Normal file
File diff suppressed because it is too large
Load Diff
195
src/osal.c
195
src/osal.c
@@ -53,6 +53,9 @@ static int ntstatus2errcode(NTSTATUS status) {
|
||||
* declare them here. Using these APIs also means we must link to
|
||||
* ntdll.dll, which is not linked by default in user code. */
|
||||
#pragma comment(lib, "ntdll.lib")
|
||||
#ifdef MDBX_AVOID_CRT
|
||||
#pragma comment(lib, "mdbx_ntdll_extra.lib")
|
||||
#endif
|
||||
|
||||
extern NTSTATUS NTAPI NtCreateSection(
|
||||
OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess,
|
||||
@@ -137,6 +140,15 @@ typedef struct _FILE_PROVIDER_EXTERNAL_INFO_V1 {
|
||||
#define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS)0xC0000010L)
|
||||
#endif
|
||||
|
||||
#ifndef FILE_DEVICE_FILE_SYSTEM
|
||||
#define FILE_DEVICE_FILE_SYSTEM 0x00000009
|
||||
#endif
|
||||
|
||||
#ifndef FSCTL_GET_EXTERNAL_BACKING
|
||||
#define FSCTL_GET_EXTERNAL_BACKING \
|
||||
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 196, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#endif
|
||||
|
||||
#endif /* _WIN32 || _WIN64 */
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@@ -145,13 +157,8 @@ typedef struct _FILE_PROVIDER_EXTERNAL_INFO_V1 {
|
||||
/* Prototype should match libc runtime. ISO POSIX (2003) & LSB 3.1 */
|
||||
__nothrow __noreturn void __assert_fail(const char *assertion, const char *file,
|
||||
unsigned line, const char *function);
|
||||
#else
|
||||
__extern_C __declspec(dllimport) void __cdecl _assert(char const *message,
|
||||
char const *filename,
|
||||
unsigned line);
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#ifndef mdbx_assert_fail
|
||||
void __cold mdbx_assert_fail(const MDBX_env *env, const char *msg,
|
||||
const char *func, int line) {
|
||||
#if MDBX_DEBUG
|
||||
@@ -165,49 +172,57 @@ void __cold mdbx_assert_fail(const MDBX_env *env, const char *msg,
|
||||
|
||||
if (mdbx_debug_logger)
|
||||
mdbx_debug_log(MDBX_DBG_ASSERT, func, line, "assert: %s\n", msg);
|
||||
#ifndef _MSC_VER
|
||||
__assert_fail(msg, "mdbx", line, func);
|
||||
else {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
char *message = nullptr;
|
||||
const int num = mdbx_asprintf(&message, "\r\nMDBX-ASSERTION: %s, %s:%u",
|
||||
msg, func ? func : "unknown", line);
|
||||
if (num < 1 || !message)
|
||||
message = "<troubles with assertion-message preparation>";
|
||||
OutputDebugStringA(message);
|
||||
if (IsDebuggerPresent())
|
||||
DebugBreak();
|
||||
#else
|
||||
_assert(msg, func, line);
|
||||
#endif /* _MSC_VER */
|
||||
__assert_fail(msg, "mdbx", line, func);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
FatalExit(ERROR_UNHANDLED_ERROR);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
#endif /* mdbx_assert_fail */
|
||||
|
||||
__cold void mdbx_panic(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
#ifdef _MSC_VER
|
||||
if (IsDebuggerPresent()) {
|
||||
OutputDebugStringA("\r\n" FIXME "\r\n");
|
||||
FatalExit(ERROR_UNHANDLED_ERROR);
|
||||
}
|
||||
#elif _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L || \
|
||||
(__GLIBC_PREREQ(1, 0) && !__GLIBC_PREREQ(2, 10) && defined(_GNU_SOURCE))
|
||||
vdprintf(STDERR_FILENO, fmt, ap);
|
||||
#else
|
||||
#error FIXME
|
||||
#endif
|
||||
|
||||
char *message = nullptr;
|
||||
const int num = mdbx_vasprintf(&message, fmt, ap);
|
||||
va_end(ap);
|
||||
if (num < 1 || !message)
|
||||
message = "<troubles with panic-message preparation>";
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
OutputDebugStringA("\r\nMDBX-PANIC: ");
|
||||
OutputDebugStringA(message);
|
||||
if (IsDebuggerPresent())
|
||||
DebugBreak();
|
||||
FatalExit(ERROR_UNHANDLED_ERROR);
|
||||
#else
|
||||
__assert_fail(message, "mdbx", 0, "panic");
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef mdbx_asprintf
|
||||
int mdbx_asprintf(char **strp, const char *fmt, ...) {
|
||||
va_list ap, ones;
|
||||
|
||||
va_start(ap, fmt);
|
||||
#ifndef mdbx_vasprintf
|
||||
int mdbx_vasprintf(char **strp, const char *fmt, va_list ap) {
|
||||
va_list ones;
|
||||
va_copy(ones, ap);
|
||||
#ifdef _MSC_VER
|
||||
int needed = _vscprintf(fmt, ap);
|
||||
#elif defined(vsnprintf) || defined(_BSD_SOURCE) || _XOPEN_SOURCE >= 500 || \
|
||||
defined(_ISOC99_SOURCE) || _POSIX_C_SOURCE >= 200112L
|
||||
int needed = vsnprintf(nullptr, 0, fmt, ap);
|
||||
#else
|
||||
#error FIXME
|
||||
#endif
|
||||
va_end(ap);
|
||||
|
||||
if (unlikely(needed < 0 || needed >= INT_MAX)) {
|
||||
*strp = nullptr;
|
||||
@@ -215,34 +230,44 @@ int mdbx_asprintf(char **strp, const char *fmt, ...) {
|
||||
return needed;
|
||||
}
|
||||
|
||||
*strp = malloc(needed + 1);
|
||||
*strp = mdbx_malloc(needed + 1);
|
||||
if (unlikely(*strp == nullptr)) {
|
||||
va_end(ones);
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
SetLastError(MDBX_ENOMEM);
|
||||
#else
|
||||
errno = MDBX_ENOMEM;
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(vsnprintf) || defined(_BSD_SOURCE) || _XOPEN_SOURCE >= 500 || \
|
||||
defined(_ISOC99_SOURCE) || _POSIX_C_SOURCE >= 200112L
|
||||
int actual = vsnprintf(*strp, needed + 1, fmt, ones);
|
||||
#else
|
||||
#error FIXME
|
||||
#endif
|
||||
va_end(ones);
|
||||
|
||||
assert(actual == needed);
|
||||
if (unlikely(actual < 0)) {
|
||||
free(*strp);
|
||||
mdbx_free(*strp);
|
||||
*strp = nullptr;
|
||||
}
|
||||
return actual;
|
||||
}
|
||||
#endif /* mdbx_vasprintf */
|
||||
|
||||
#ifndef mdbx_asprintf
|
||||
int mdbx_asprintf(char **strp, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int rc = mdbx_vasprintf(strp, fmt, ap);
|
||||
va_end(ap);
|
||||
return rc;
|
||||
}
|
||||
#endif /* mdbx_asprintf */
|
||||
|
||||
#ifndef mdbx_memalign_alloc
|
||||
int mdbx_memalign_alloc(size_t alignment, size_t bytes, void **result) {
|
||||
#if _MSC_VER
|
||||
*result = _aligned_malloc(bytes, alignment);
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
(void)alignment;
|
||||
*result = VirtualAlloc(NULL, bytes, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
return *result ? MDBX_SUCCESS : MDBX_ENOMEM /* ERROR_OUTOFMEMORY */;
|
||||
#elif __GLIBC_PREREQ(2, 16) || __STDC_VERSION__ >= 201112L
|
||||
*result = memalign(alignment, bytes);
|
||||
@@ -258,14 +283,26 @@ int mdbx_memalign_alloc(size_t alignment, size_t bytes, void **result) {
|
||||
|
||||
#ifndef mdbx_memalign_free
|
||||
void mdbx_memalign_free(void *ptr) {
|
||||
#if _MSC_VER
|
||||
_aligned_free(ptr);
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
VirtualFree(ptr, 0, MEM_RELEASE);
|
||||
#else
|
||||
free(ptr);
|
||||
mdbx_free(ptr);
|
||||
#endif
|
||||
}
|
||||
#endif /* mdbx_memalign_free */
|
||||
|
||||
#ifndef mdbx_strdup
|
||||
char *mdbx_strdup(const char *str) {
|
||||
if (!str)
|
||||
return NULL;
|
||||
size_t bytes = strlen(str) + 1;
|
||||
char *dup = mdbx_malloc(bytes);
|
||||
if (dup)
|
||||
memcpy(dup, str, bytes);
|
||||
return dup;
|
||||
}
|
||||
#endif /* mdbx_strdup */
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
int mdbx_condmutex_init(mdbx_condmutex_t *condmutex) {
|
||||
@@ -716,6 +753,19 @@ int mdbx_ftruncate(mdbx_filehandle_t fd, uint64_t length) {
|
||||
#endif
|
||||
}
|
||||
|
||||
int mdbx_fseek(mdbx_filehandle_t fd, uint64_t pos) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
LARGE_INTEGER li;
|
||||
li.QuadPart = pos;
|
||||
return SetFilePointerEx(fd, li, NULL, FILE_BEGIN) ? MDBX_SUCCESS
|
||||
: GetLastError();
|
||||
#else
|
||||
STATIC_ASSERT_MSG(sizeof(off_t) >= sizeof(size_t),
|
||||
"libmdbx requires 64-bit file I/O on 64-bit systems");
|
||||
return (lseek(fd, pos, SEEK_SET) < 0) ? errno : MDBX_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
int mdbx_thread_create(mdbx_thread_t *thread,
|
||||
@@ -797,33 +847,47 @@ int mdbx_check4nonlocal(mdbx_filehandle_t handle, int flags) {
|
||||
}
|
||||
|
||||
if (mdbx_GetVolumeInformationByHandleW && mdbx_GetFinalPathNameByHandleW) {
|
||||
WCHAR PathBuffer[INT16_MAX];
|
||||
WCHAR *PathBuffer = mdbx_malloc(sizeof(WCHAR) * INT16_MAX);
|
||||
if (!PathBuffer)
|
||||
return MDBX_ENOMEM;
|
||||
|
||||
int rc = MDBX_SUCCESS;
|
||||
DWORD VolumeSerialNumber, FileSystemFlags;
|
||||
if (!mdbx_GetVolumeInformationByHandleW(handle, PathBuffer, INT16_MAX,
|
||||
&VolumeSerialNumber, NULL,
|
||||
&FileSystemFlags, NULL, 0))
|
||||
return GetLastError();
|
||||
&FileSystemFlags, NULL, 0)) {
|
||||
rc = GetLastError();
|
||||
goto bailout;
|
||||
}
|
||||
|
||||
if ((flags & MDBX_RDONLY) == 0) {
|
||||
if (FileSystemFlags & (FILE_SEQUENTIAL_WRITE_ONCE |
|
||||
FILE_READ_ONLY_VOLUME | FILE_VOLUME_IS_COMPRESSED))
|
||||
return ERROR_REMOTE_STORAGE_MEDIA_ERROR;
|
||||
if (FileSystemFlags &
|
||||
(FILE_SEQUENTIAL_WRITE_ONCE | FILE_READ_ONLY_VOLUME |
|
||||
FILE_VOLUME_IS_COMPRESSED)) {
|
||||
rc = ERROR_REMOTE_STORAGE_MEDIA_ERROR;
|
||||
goto bailout;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mdbx_GetFinalPathNameByHandleW(handle, PathBuffer, INT16_MAX,
|
||||
FILE_NAME_NORMALIZED | VOLUME_NAME_NT))
|
||||
return GetLastError();
|
||||
FILE_NAME_NORMALIZED |
|
||||
VOLUME_NAME_NT)) {
|
||||
rc = GetLastError();
|
||||
goto bailout;
|
||||
}
|
||||
|
||||
if (_wcsnicmp(PathBuffer, L"\\Device\\Mup\\", 12) == 0) {
|
||||
if (!(flags & MDBX_EXCLUSIVE))
|
||||
return ERROR_REMOTE_STORAGE_MEDIA_ERROR;
|
||||
if (!(flags & MDBX_EXCLUSIVE)) {
|
||||
rc = ERROR_REMOTE_STORAGE_MEDIA_ERROR;
|
||||
goto bailout;
|
||||
}
|
||||
} else if (mdbx_GetFinalPathNameByHandleW(handle, PathBuffer, INT16_MAX,
|
||||
FILE_NAME_NORMALIZED |
|
||||
VOLUME_NAME_DOS)) {
|
||||
UINT DriveType = GetDriveTypeW(PathBuffer);
|
||||
if (DriveType == DRIVE_NO_ROOT_DIR &&
|
||||
wcsncmp(PathBuffer, L"\\\\?\\", 4) == 0 &&
|
||||
wcsncmp(PathBuffer + 5, L":\\", 2) == 0) {
|
||||
_wcsnicmp(PathBuffer, L"\\\\?\\", 4) == 0 &&
|
||||
_wcsnicmp(PathBuffer + 5, L":\\", 2) == 0) {
|
||||
PathBuffer[7] = 0;
|
||||
DriveType = GetDriveTypeW(PathBuffer + 4);
|
||||
}
|
||||
@@ -837,7 +901,7 @@ int mdbx_check4nonlocal(mdbx_filehandle_t handle, int flags) {
|
||||
case DRIVE_REMOTE:
|
||||
default:
|
||||
if (!(flags & MDBX_EXCLUSIVE))
|
||||
return ERROR_REMOTE_STORAGE_MEDIA_ERROR;
|
||||
rc = ERROR_REMOTE_STORAGE_MEDIA_ERROR;
|
||||
// fall through
|
||||
case DRIVE_REMOVABLE:
|
||||
case DRIVE_FIXED:
|
||||
@@ -845,6 +909,9 @@ int mdbx_check4nonlocal(mdbx_filehandle_t handle, int flags) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
bailout:
|
||||
mdbx_free(PathBuffer);
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
(void)handle;
|
||||
@@ -1017,11 +1084,11 @@ int mdbx_mresize(int flags, mdbx_mmap_t *map, size_t size, size_t limit) {
|
||||
&ReservedSize, MEM_RESERVE, PAGE_NOACCESS);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
ReservedAddress = NULL;
|
||||
if (status != /* STATUS_CONFLICTING_ADDRESSES */ 0xC0000018 ||
|
||||
limit == map->length)
|
||||
if (status != /* STATUS_CONFLICTING_ADDRESSES */ 0xC0000018)
|
||||
goto bailout_ntstatus /* no way to recovery */;
|
||||
|
||||
/* assume we can change base address if mapping size changed */
|
||||
/* assume we can change base address if mapping size changed or prev address
|
||||
* couldn't be used */
|
||||
map->address = NULL;
|
||||
}
|
||||
|
||||
@@ -1078,8 +1145,8 @@ retry_mapview:;
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
if (status == /* STATUS_CONFLICTING_ADDRESSES */ 0xC0000018 &&
|
||||
map->address && limit != map->length) {
|
||||
/* try remap at another base address, but only if the limit is changing */
|
||||
map->address) {
|
||||
/* try remap at another base address */
|
||||
map->address = NULL;
|
||||
goto retry_mapview;
|
||||
}
|
||||
|
||||
112
src/osal.h
112
src/osal.h
@@ -28,10 +28,16 @@
|
||||
#pragma warning(disable : 4577) /* 'noexcept' used with no exception handling \
|
||||
* mode specified; termination on exception is \
|
||||
* not guaranteed. Specify /EHsc */
|
||||
#endif /* _MSC_VER (warnings) */
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#endif /* _MSC_VER (warnings) */
|
||||
#if !defined(_NO_CRT_STDIO_INLINE) && defined(MDBX_BUILD_DLL)
|
||||
#define _NO_CRT_STDIO_INLINE
|
||||
#endif
|
||||
#endif /* Windows */
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* C99 includes */
|
||||
@@ -84,7 +90,47 @@ typedef struct {
|
||||
HANDLE event;
|
||||
} mdbx_condmutex_t;
|
||||
typedef CRITICAL_SECTION mdbx_fastmutex_t;
|
||||
|
||||
#ifdef MDBX_AVOID_CRT
|
||||
#ifndef mdbx_malloc
|
||||
static inline void *mdbx_malloc(size_t bytes) {
|
||||
return LocalAlloc(LMEM_FIXED, bytes);
|
||||
}
|
||||
#endif /* mdbx_malloc */
|
||||
|
||||
#ifndef mdbx_calloc
|
||||
static inline void *mdbx_calloc(size_t nelem, size_t size) {
|
||||
return LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, nelem * size);
|
||||
}
|
||||
#endif /* mdbx_calloc */
|
||||
|
||||
#ifndef mdbx_realloc
|
||||
static inline void *mdbx_realloc(void *ptr, size_t bytes) {
|
||||
return LocalReAlloc(ptr, bytes, LMEM_MOVEABLE);
|
||||
}
|
||||
#endif /* mdbx_realloc */
|
||||
|
||||
#ifndef mdbx_free
|
||||
#define mdbx_free LocalFree
|
||||
#endif /* mdbx_free */
|
||||
#else
|
||||
#define mdbx_malloc malloc
|
||||
#define mdbx_calloc calloc
|
||||
#define mdbx_realloc realloc
|
||||
#define mdbx_free free
|
||||
#define mdbx_strdup _strdup
|
||||
#endif /* MDBX_AVOID_CRT */
|
||||
|
||||
#ifndef snprintf
|
||||
#define snprintf _snprintf /* ntdll */
|
||||
#endif
|
||||
|
||||
#ifndef vsnprintf
|
||||
#define vsnprintf _vsnprintf /* ntdll */
|
||||
#endif
|
||||
|
||||
#else /*----------------------------------------------------------------------*/
|
||||
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <sys/file.h>
|
||||
@@ -103,6 +149,11 @@ typedef struct {
|
||||
pthread_cond_t cond;
|
||||
} mdbx_condmutex_t;
|
||||
typedef pthread_mutex_t mdbx_fastmutex_t;
|
||||
#define mdbx_malloc malloc
|
||||
#define mdbx_calloc calloc
|
||||
#define mdbx_realloc realloc
|
||||
#define mdbx_free free
|
||||
#define mdbx_strdup strdup
|
||||
#endif /* Platform */
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
@@ -379,36 +430,14 @@ static __inline void mdbx_invalidate_cache(void *addr, size_t nbytes) {
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* libc compatibility stuff */
|
||||
|
||||
#ifndef mdbx_assert_fail
|
||||
void mdbx_assert_fail(const MDBX_env *env, const char *msg, const char *func,
|
||||
int line);
|
||||
#endif /* mdbx_assert_fail */
|
||||
|
||||
#if __GLIBC_PREREQ(2, 1)
|
||||
#define mdbx_asprintf asprintf
|
||||
#define mdbx_vasprintf vasprintf
|
||||
#else
|
||||
int mdbx_asprintf(char **strp, const char *fmt, ...);
|
||||
__printf_args(2, 3) int mdbx_asprintf(char **strp, const char *fmt, ...);
|
||||
int mdbx_vasprintf(char **strp, const char *fmt, va_list ap);
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#ifndef snprintf
|
||||
#define snprintf(buffer, buffer_size, format, ...) \
|
||||
_snprintf_s(buffer, buffer_size, _TRUNCATE, format, __VA_ARGS__)
|
||||
#endif /* snprintf */
|
||||
|
||||
#ifndef vsnprintf
|
||||
#define vsnprintf(buffer, buffer_size, format, args) \
|
||||
_vsnprintf_s(buffer, buffer_size, _TRUNCATE, format, args)
|
||||
#endif /* vsnprintf */
|
||||
|
||||
#ifdef _ASSERTE
|
||||
#undef assert
|
||||
#define assert _ASSERTE
|
||||
#endif
|
||||
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* OS abstraction layer stuff */
|
||||
|
||||
@@ -428,13 +457,9 @@ static __inline size_t mdbx_syspagesize(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline char *mdbx_strdup(const char *str) {
|
||||
#ifdef _MSC_VER
|
||||
return _strdup(str);
|
||||
#else
|
||||
return strdup(str);
|
||||
#ifndef mdbx_strdup
|
||||
LIBMDBX_API char *mdbx_strdup(const char *str);
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline int mdbx_get_errno(void) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
@@ -445,8 +470,12 @@ static __inline int mdbx_get_errno(void) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifndef mdbx_memalign_alloc
|
||||
int mdbx_memalign_alloc(size_t alignment, size_t bytes, void **result);
|
||||
#endif
|
||||
#ifndef mdbx_memalign_free
|
||||
void mdbx_memalign_free(void *ptr);
|
||||
#endif
|
||||
|
||||
int mdbx_condmutex_init(mdbx_condmutex_t *condmutex);
|
||||
int mdbx_condmutex_lock(mdbx_condmutex_t *condmutex);
|
||||
@@ -475,6 +504,7 @@ int mdbx_thread_join(mdbx_thread_t thread);
|
||||
int mdbx_filesync(mdbx_filehandle_t fd, bool fullsync);
|
||||
int mdbx_filesize_sync(mdbx_filehandle_t fd);
|
||||
int mdbx_ftruncate(mdbx_filehandle_t fd, uint64_t length);
|
||||
int mdbx_fseek(mdbx_filehandle_t fd, uint64_t pos);
|
||||
int mdbx_filesize(mdbx_filehandle_t fd, uint64_t *length);
|
||||
int mdbx_openfile(const char *pathname, int flags, mode_t mode,
|
||||
mdbx_filehandle_t *fd, bool exclusive);
|
||||
@@ -564,14 +594,12 @@ int mdbx_rpid_set(MDBX_env *env);
|
||||
int mdbx_rpid_clear(MDBX_env *env);
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
typedef struct MDBX_srwlock {
|
||||
union {
|
||||
struct {
|
||||
long volatile readerCount;
|
||||
long volatile writerCount;
|
||||
};
|
||||
RTL_SRWLOCK native;
|
||||
typedef union MDBX_srwlock {
|
||||
struct {
|
||||
long volatile readerCount;
|
||||
long volatile writerCount;
|
||||
};
|
||||
RTL_SRWLOCK native;
|
||||
} MDBX_srwlock;
|
||||
|
||||
typedef void(WINAPI *MDBX_srwlock_function)(MDBX_srwlock *);
|
||||
@@ -652,7 +680,8 @@ static __inline uint32_t mdbx_atomic_add32(volatile uint32_t *p, uint32_t v) {
|
||||
return __sync_fetch_and_add(p, v);
|
||||
#else
|
||||
#ifdef _MSC_VER
|
||||
return _InterlockedExchangeAdd(p, v);
|
||||
STATIC_ASSERT(sizeof(volatile long) == sizeof(volatile uint32_t));
|
||||
return _InterlockedExchangeAdd((volatile long *)p, v);
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
return OSAtomicAdd32(v, (volatile int32_t *)p);
|
||||
@@ -692,7 +721,8 @@ static __inline bool mdbx_atomic_compare_and_swap32(volatile uint32_t *p,
|
||||
return __sync_bool_compare_and_swap(p, c, v);
|
||||
#else
|
||||
#ifdef _MSC_VER
|
||||
return c == _InterlockedCompareExchange(p, v, c);
|
||||
STATIC_ASSERT(sizeof(volatile long) == sizeof(volatile uint32_t));
|
||||
return c == _InterlockedCompareExchange((volatile long *)p, v, c);
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
return c == OSAtomicCompareAndSwap32Barrier(c, v, (volatile int32_t *)p);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* mdbx_chk.c - memory-mapped database check tool */
|
||||
/* mdbx_chk.c - memory-mapped database check tool */
|
||||
|
||||
/*
|
||||
* Copyright 2015-2018 Leonid Yuriev <leo@yuriev.ru>
|
||||
@@ -97,7 +97,7 @@ const char *only_subdb;
|
||||
|
||||
struct problem {
|
||||
struct problem *pr_next;
|
||||
uint64_t count;
|
||||
size_t count;
|
||||
const char *caption;
|
||||
};
|
||||
|
||||
@@ -141,12 +141,12 @@ static void
|
||||
static void pagemap_cleanup(void) {
|
||||
for (int i = CORE_DBS; ++i < MAX_DBI;) {
|
||||
if (walk.dbi[i].name) {
|
||||
free((void *)walk.dbi[i].name);
|
||||
mdbx_free((void *)walk.dbi[i].name);
|
||||
walk.dbi[i].name = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
free(walk.pagemap);
|
||||
mdbx_free(walk.pagemap);
|
||||
walk.pagemap = NULL;
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ static walk_dbi_t *pagemap_lookup_dbi(const char *dbi_name, bool silent) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dbi->name = strdup(dbi_name);
|
||||
dbi->name = mdbx_strdup(dbi_name);
|
||||
if (verbose > 1 && !silent) {
|
||||
print(" - found '%s' area\n", dbi_name);
|
||||
fflush(NULL);
|
||||
@@ -190,7 +190,7 @@ static void
|
||||
break;
|
||||
|
||||
if (!p) {
|
||||
p = calloc(1, sizeof(*p));
|
||||
p = mdbx_calloc(1, sizeof(*p));
|
||||
p->caption = msg;
|
||||
p->pr_next = problems_list;
|
||||
problems_list = p;
|
||||
@@ -221,8 +221,8 @@ static struct problem *problems_push(void) {
|
||||
return p;
|
||||
}
|
||||
|
||||
static uint64_t problems_pop(struct problem *list) {
|
||||
uint64_t count = 0;
|
||||
static size_t problems_pop(struct problem *list) {
|
||||
size_t count = 0;
|
||||
|
||||
if (problems_list) {
|
||||
int i;
|
||||
@@ -231,9 +231,9 @@ static uint64_t problems_pop(struct problem *list) {
|
||||
for (i = 0; problems_list; ++i) {
|
||||
struct problem *p = problems_list->pr_next;
|
||||
count += problems_list->count;
|
||||
print("%s%s (%" PRIu64 ")", i ? ", " : "", problems_list->caption,
|
||||
print("%s%s (%" PRIuPTR ")", i ? ", " : "", problems_list->caption,
|
||||
problems_list->count);
|
||||
free(problems_list);
|
||||
mdbx_free(problems_list);
|
||||
problems_list = p;
|
||||
}
|
||||
print("\n");
|
||||
@@ -267,7 +267,7 @@ static int pgvisitor(uint64_t pgno, unsigned pgnumber, void *ctx, int deep,
|
||||
else
|
||||
problem_add("deep", deep, "unknown area", "%s", dbi_name);
|
||||
|
||||
const uint64_t page_bytes = payload_bytes + header_bytes + unused_bytes;
|
||||
const size_t page_bytes = payload_bytes + header_bytes + unused_bytes;
|
||||
walk.pgcount += pgnumber;
|
||||
|
||||
const char *pagetype_caption;
|
||||
@@ -351,7 +351,7 @@ static int pgvisitor(uint64_t pgno, unsigned pgnumber, void *ctx, int deep,
|
||||
if (pgnumber) {
|
||||
if (page_bytes != page_size) {
|
||||
problem_add("page", pgno, "misused",
|
||||
"%s-page: %" PRIu64 " != %" PRIu64 " (%" PRIuPTR
|
||||
"%s-page: %" PRIuPTR " != %" PRIuPTR " (%" PRIuPTR
|
||||
"h + %" PRIuPTR "p + %" PRIuPTR "u)",
|
||||
pagetype_caption, page_size, page_bytes, header_bytes,
|
||||
payload_bytes, unused_bytes);
|
||||
@@ -497,13 +497,13 @@ static int handle_maindb(const uint64_t record_number, const MDBX_val *key,
|
||||
return handle_userdb(record_number, key, data);
|
||||
}
|
||||
|
||||
name = malloc(key->iov_len + 1);
|
||||
name = mdbx_malloc(key->iov_len + 1);
|
||||
memcpy(name, key->iov_base, key->iov_len);
|
||||
name[key->iov_len] = '\0';
|
||||
userdb_count++;
|
||||
|
||||
rc = process_db(~0u, name, handle_userdb, false);
|
||||
free(name);
|
||||
mdbx_free(name);
|
||||
if (rc != MDBX_INCOMPATIBLE)
|
||||
return rc;
|
||||
|
||||
@@ -689,7 +689,7 @@ static int process_db(MDBX_dbi dbi_handle, char *dbi_name, visitor *handler,
|
||||
|
||||
if (record_count != ms.ms_entries)
|
||||
problem_add("entry", record_count, "differentent number of entries",
|
||||
"%" PRIuPTR " != %" PRIuPTR, record_count, ms.ms_entries);
|
||||
"%" PRIu64 " != %" PRIu64, record_count, ms.ms_entries);
|
||||
bailout:
|
||||
problems_count = problems_pop(saved_list);
|
||||
if (!silent && verbose) {
|
||||
@@ -1088,12 +1088,12 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
if (!dont_traversal) {
|
||||
struct problem *saved_list;
|
||||
uint64_t traversal_problems;
|
||||
size_t traversal_problems;
|
||||
uint64_t empty_pages, lost_bytes;
|
||||
|
||||
print("Traversal b-tree by txn#%" PRIaTXN "...\n", txn->mt_txnid);
|
||||
fflush(NULL);
|
||||
walk.pagemap = calloc((size_t)lastpgno, sizeof(*walk.pagemap));
|
||||
walk.pagemap = mdbx_calloc((size_t)lastpgno, sizeof(*walk.pagemap));
|
||||
if (!walk.pagemap) {
|
||||
rc = errno ? errno : MDBX_ENOMEM;
|
||||
error("calloc failed, error %d %s\n", rc, mdbx_strerror(rc));
|
||||
@@ -1181,9 +1181,9 @@ int main(int argc, char *argv[]) {
|
||||
print(" - summary: average fill %.1f%%",
|
||||
walk.total_payload_bytes * 100.0 / total_page_bytes);
|
||||
if (empty_pages)
|
||||
print(", %" PRIuPTR " empty pages", empty_pages);
|
||||
print(", %" PRIu64 " empty pages", empty_pages);
|
||||
if (lost_bytes)
|
||||
print(", %" PRIuPTR " bytes lost", lost_bytes);
|
||||
print(", %" PRIu64 " bytes lost", lost_bytes);
|
||||
print(", %" PRIuPTR " problems\n", traversal_problems);
|
||||
}
|
||||
} else if (verbose) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
|
||||
@@ -203,7 +203,8 @@ int main(int argc, char *argv[]) {
|
||||
break;
|
||||
case 'f':
|
||||
if (freopen(optarg, "w", stdout) == NULL) {
|
||||
fprintf(stderr, "%s: %s: reopen: %s\n", prog, optarg, strerror(errno));
|
||||
fprintf(stderr, "%s: %s: reopen: %s\n", prog, optarg,
|
||||
mdbx_strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
@@ -292,7 +293,7 @@ int main(int argc, char *argv[]) {
|
||||
if (memchr(key.iov_base, '\0', key.iov_len))
|
||||
continue;
|
||||
count++;
|
||||
str = malloc(key.iov_len + 1);
|
||||
str = mdbx_malloc(key.iov_len + 1);
|
||||
memcpy(str, key.iov_base, key.iov_len);
|
||||
str[key.iov_len] = '\0';
|
||||
rc = mdbx_dbi_open(txn, str, 0, &db2);
|
||||
@@ -307,7 +308,7 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
mdbx_dbi_close(env, db2);
|
||||
}
|
||||
free(str);
|
||||
mdbx_free(str);
|
||||
if (rc)
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
|
||||
@@ -110,8 +110,8 @@ static void readhdr(void) {
|
||||
if (ptr)
|
||||
*ptr = '\0';
|
||||
if (subname)
|
||||
free(subname);
|
||||
subname = strdup((char *)dbuf.iov_base + STRLENOF("database="));
|
||||
mdbx_free(subname);
|
||||
subname = mdbx_strdup((char *)dbuf.iov_base + STRLENOF("database="));
|
||||
} else if (!strncmp(dbuf.iov_base, "type=", STRLENOF("type="))) {
|
||||
if (strncmp((char *)dbuf.iov_base + STRLENOF("type="), "btree",
|
||||
STRLENOF("btree"))) {
|
||||
@@ -237,7 +237,7 @@ static int readline(MDBX_val *out, MDBX_val *buf) {
|
||||
|
||||
/* Is buffer too short? */
|
||||
while (c1[len - 1] != '\n') {
|
||||
buf->iov_base = realloc(buf->iov_base, buf->iov_len * 2);
|
||||
buf->iov_base = mdbx_realloc(buf->iov_base, buf->iov_len * 2);
|
||||
if (!buf->iov_base) {
|
||||
Eof = 1;
|
||||
fprintf(stderr, "%s: line %" PRIiSIZE ": out of memory, line too long\n",
|
||||
@@ -340,7 +340,8 @@ int main(int argc, char *argv[]) {
|
||||
break;
|
||||
case 'f':
|
||||
if (freopen(optarg, "r", stdin) == NULL) {
|
||||
fprintf(stderr, "%s: %s: reopen: %s\n", prog, optarg, strerror(errno));
|
||||
fprintf(stderr, "%s: %s: reopen: %s\n", prog, optarg,
|
||||
mdbx_strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
@@ -348,7 +349,7 @@ int main(int argc, char *argv[]) {
|
||||
envflags |= MDBX_NOSUBDIR;
|
||||
break;
|
||||
case 's':
|
||||
subname = strdup(optarg);
|
||||
subname = mdbx_strdup(optarg);
|
||||
break;
|
||||
case 'N':
|
||||
putflags = MDBX_NOOVERWRITE | MDBX_NODUPDATA;
|
||||
@@ -378,7 +379,7 @@ int main(int argc, char *argv[]) {
|
||||
#endif /* !WINDOWS */
|
||||
|
||||
dbuf.iov_len = 4096;
|
||||
dbuf.iov_base = malloc(dbuf.iov_len);
|
||||
dbuf.iov_base = mdbx_malloc(dbuf.iov_len);
|
||||
|
||||
if (!(mode & NOHDR))
|
||||
readhdr();
|
||||
@@ -418,7 +419,7 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
kbuf.iov_len = mdbx_env_get_maxkeysize(env) * 2 + 2;
|
||||
kbuf.iov_base = malloc(kbuf.iov_len);
|
||||
kbuf.iov_base = mdbx_malloc(kbuf.iov_len);
|
||||
|
||||
while (!Eof) {
|
||||
if (user_break) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
|
||||
@@ -356,13 +356,13 @@ int main(int argc, char *argv[]) {
|
||||
MDBX_dbi db2;
|
||||
if (memchr(key.iov_base, '\0', key.iov_len))
|
||||
continue;
|
||||
str = malloc(key.iov_len + 1);
|
||||
str = mdbx_malloc(key.iov_len + 1);
|
||||
memcpy(str, key.iov_base, key.iov_len);
|
||||
str[key.iov_len] = '\0';
|
||||
rc = mdbx_dbi_open(txn, str, 0, &db2);
|
||||
if (rc == MDBX_SUCCESS)
|
||||
printf("Status of %s\n", str);
|
||||
free(str);
|
||||
mdbx_free(str);
|
||||
if (rc)
|
||||
continue;
|
||||
rc = mdbx_dbi_stat(txn, db2, &mst, sizeof(mst));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
|
||||
@@ -55,7 +55,7 @@ char *optarg;
|
||||
int getopt(int argc, char *const argv[], const char *opts) {
|
||||
static int sp = 1;
|
||||
int c;
|
||||
char *cp;
|
||||
const char *cp;
|
||||
|
||||
if (sp == 1) {
|
||||
if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||
|
||||
@@ -1,34 +1,35 @@
|
||||
set(TARGET mdbx_test)
|
||||
set(TARGET mdbx_test)
|
||||
project(${TARGET})
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-declarations")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-cast-qual")
|
||||
|
||||
add_executable(${TARGET}
|
||||
base.h
|
||||
cases.cc
|
||||
chrono.cc
|
||||
chrono.h
|
||||
config.cc
|
||||
config.h
|
||||
dead.cc
|
||||
hill.cc
|
||||
jitter.cc
|
||||
keygen.cc
|
||||
keygen.h
|
||||
log.cc
|
||||
log.h
|
||||
main.cc
|
||||
osal.h
|
||||
osal-unix.cc
|
||||
test.cc
|
||||
test.h
|
||||
try.cc
|
||||
utils.cc
|
||||
utils.h
|
||||
)
|
||||
base.h
|
||||
cases.cc
|
||||
chrono.cc
|
||||
chrono.h
|
||||
config.cc
|
||||
config.h
|
||||
copy.cc
|
||||
dead.cc
|
||||
hill.cc
|
||||
jitter.cc
|
||||
keygen.cc
|
||||
keygen.h
|
||||
log.cc
|
||||
log.h
|
||||
main.cc
|
||||
osal.h
|
||||
osal-unix.cc
|
||||
test.cc
|
||||
test.h
|
||||
try.cc
|
||||
utils.cc
|
||||
utils.h
|
||||
)
|
||||
|
||||
target_link_libraries(${TARGET}
|
||||
mdbx
|
||||
)
|
||||
mdbx
|
||||
)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2017-2018 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
@@ -68,6 +68,7 @@ void testcase_setup(const char *casename, actor_params ¶ms,
|
||||
configure_actor(last_space_id, ac_jitter, nullptr, params);
|
||||
configure_actor(last_space_id, ac_hill, nullptr, params);
|
||||
configure_actor(last_space_id, ac_try, nullptr, params);
|
||||
configure_actor(last_space_id, ac_copy, nullptr, params);
|
||||
log_notice("<<< testcase_setup(%s): done", casename);
|
||||
} else {
|
||||
failure("unknown testcase `%s`", casename);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2017-2018 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
@@ -26,7 +26,8 @@ enum actor_testcase {
|
||||
ac_deadread,
|
||||
ac_deadwrite,
|
||||
ac_jitter,
|
||||
ac_try
|
||||
ac_try,
|
||||
ac_copy
|
||||
};
|
||||
|
||||
enum actor_status {
|
||||
|
||||
26
test/copy.cc
Normal file
26
test/copy.cc
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "test.h"
|
||||
|
||||
void testcase_copy::copy_db(const bool with_compaction) {
|
||||
int err = osal_removefile(copy_pathname);
|
||||
if (err != MDBX_SUCCESS && err != MDBX_ENOFILE)
|
||||
failure_perror("mdbx_removefile()", err);
|
||||
|
||||
err = mdbx_env_copy(db_guard.get(), copy_pathname.c_str(),
|
||||
with_compaction ? MDBX_CP_COMPACT : 0);
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
failure_perror(with_compaction ? "mdbx_env_copy(MDBX_CP_COMPACT)"
|
||||
: "mdbx_env_copy(MDBX_CP_ASIS)",
|
||||
err);
|
||||
}
|
||||
|
||||
bool testcase_copy::run() {
|
||||
jitter_delay();
|
||||
db_open();
|
||||
assert(!txn_guard);
|
||||
const bool order = flipcoin();
|
||||
jitter_delay();
|
||||
copy_db(order);
|
||||
jitter_delay();
|
||||
copy_db(!order);
|
||||
return true;
|
||||
}
|
||||
42
test/dead.cc
42
test/dead.cc
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2017-2018 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
@@ -14,50 +14,22 @@
|
||||
|
||||
#include "test.h"
|
||||
|
||||
bool testcase_deadread::setup() {
|
||||
log_trace(">> setup");
|
||||
if (!inherited::setup())
|
||||
return false;
|
||||
|
||||
log_trace("<< setup");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testcase_deadread::run() {
|
||||
db_open();
|
||||
txn_begin(true);
|
||||
cursor_guard.reset();
|
||||
txn_guard.reset();
|
||||
db_guard.reset();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testcase_deadread::teardown() {
|
||||
log_trace(">> teardown");
|
||||
cursor_guard.release();
|
||||
txn_guard.release();
|
||||
db_guard.release();
|
||||
return inherited::teardown();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool testcase_deadwrite::setup() {
|
||||
log_trace(">> setup");
|
||||
if (!inherited::setup())
|
||||
return false;
|
||||
|
||||
log_trace("<< setup");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testcase_deadwrite::run() {
|
||||
db_open();
|
||||
txn_begin(false);
|
||||
cursor_guard.reset();
|
||||
txn_guard.reset();
|
||||
db_guard.reset();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testcase_deadwrite::teardown() {
|
||||
log_trace(">> teardown");
|
||||
cursor_guard.release();
|
||||
txn_guard.release();
|
||||
db_guard.release();
|
||||
return inherited::teardown();
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ function probe {
|
||||
rm -f ${TESTDB_PREFIX}* \
|
||||
&& ./mdbx_test --pathname=${TESTDB_PREFIX}db "$@" | lz4 > ${TESTDB_PREFIX}log.lz4 \
|
||||
&& ./mdbx_chk -nvvv ${TESTDB_PREFIX}db | tee ${TESTDB_PREFIX}chk \
|
||||
&& ./mdbx_chk -nvvv ${TESTDB_PREFIX}db-copy | tee ${TESTDB_PREFIX}chk-copy \
|
||||
|| (echo "FAILED"; exit 1)
|
||||
}
|
||||
|
||||
|
||||
18
test/hill.cc
18
test/hill.cc
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2017-2018 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
@@ -14,17 +14,6 @@
|
||||
|
||||
#include "test.h"
|
||||
|
||||
bool testcase_hill::setup() {
|
||||
log_trace(">> setup");
|
||||
if (!inherited::setup())
|
||||
return false;
|
||||
|
||||
/* TODO */
|
||||
|
||||
log_trace("<< setup");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testcase_hill::run() {
|
||||
db_open();
|
||||
|
||||
@@ -225,8 +214,3 @@ bool testcase_hill::run() {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testcase_hill::teardown() {
|
||||
log_trace(">> teardown");
|
||||
return inherited::teardown();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2017-2018 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
@@ -14,15 +14,6 @@
|
||||
|
||||
#include "test.h"
|
||||
|
||||
bool testcase_jitter::setup() {
|
||||
log_trace(">> setup");
|
||||
if (!inherited::setup())
|
||||
return false;
|
||||
|
||||
log_trace("<< setup");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testcase_jitter::run() {
|
||||
while (should_continue()) {
|
||||
jitter_delay();
|
||||
@@ -66,8 +57,3 @@ bool testcase_jitter::run() {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testcase_jitter::teardown() {
|
||||
log_trace(">> teardown");
|
||||
return inherited::teardown();
|
||||
}
|
||||
|
||||
@@ -337,6 +337,10 @@ int main(int argc, char *const argv[]) {
|
||||
configure_actor(last_space_id, ac_deadwrite, value, params);
|
||||
continue;
|
||||
}
|
||||
if (config::parse_option(argc, argv, narg, "copy", nullptr)) {
|
||||
configure_actor(last_space_id, ac_copy, value, params);
|
||||
continue;
|
||||
}
|
||||
if (config::parse_option(argc, argv, narg, "failfast",
|
||||
global::config::failfast))
|
||||
continue;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2017-2018 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
@@ -184,7 +184,7 @@ void osal_killall_actors(void) {
|
||||
int osal_actor_poll(mdbx_pid_t &pid, unsigned timeout) {
|
||||
struct timespec ts;
|
||||
ts.tv_nsec = 0;
|
||||
ts.tv_sec = timeout;
|
||||
ts.tv_sec = (timeout > INT_MAX) ? INT_MAX : timeout;
|
||||
retry:
|
||||
int status, options = WNOHANG;
|
||||
#ifdef WUNTRACED
|
||||
@@ -301,3 +301,7 @@ std::string osal_tempdir(void) {
|
||||
return "/dev/shm/";
|
||||
return "";
|
||||
}
|
||||
|
||||
int osal_removefile(const std::string &pathname) {
|
||||
return unlink(pathname.c_str()) ? errno : MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2017-2018 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
@@ -405,3 +405,7 @@ std::string osal_tempdir(void) {
|
||||
DWORD len = GetTempPathA(sizeof(buf), buf);
|
||||
return std::string(buf, len);
|
||||
}
|
||||
|
||||
int osal_removefile(const std::string &pathname) {
|
||||
return DeleteFileA(pathname.c_str()) ? MDBX_SUCCESS : GetLastError();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2017-2018 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
@@ -32,6 +32,7 @@ void osal_udelay(unsigned us);
|
||||
void osal_yield(void);
|
||||
bool osal_istty(int fd);
|
||||
std::string osal_tempdir(void);
|
||||
int osal_removefile(const std::string &pathname);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifndef STDIN_FILENO
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2017-2018 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
@@ -31,6 +31,8 @@ const char *testcase2str(const actor_testcase testcase) {
|
||||
return "jitter";
|
||||
case ac_try:
|
||||
return "try";
|
||||
case ac_copy:
|
||||
return "copy";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,6 +455,9 @@ bool test_execute(const actor_config &config) {
|
||||
case ac_try:
|
||||
test.reset(new testcase_try(config, pid));
|
||||
break;
|
||||
case ac_copy:
|
||||
test.reset(new testcase_copy(config, pid));
|
||||
break;
|
||||
default:
|
||||
test.reset(new testcase(config, pid));
|
||||
break;
|
||||
|
||||
33
test/test.h
33
test/test.h
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2017-2018 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
@@ -152,56 +152,47 @@ public:
|
||||
};
|
||||
|
||||
class testcase_hill : public testcase {
|
||||
typedef testcase inherited;
|
||||
|
||||
public:
|
||||
testcase_hill(const actor_config &config, const mdbx_pid_t pid)
|
||||
: testcase(config, pid) {}
|
||||
bool setup();
|
||||
bool run();
|
||||
bool teardown();
|
||||
};
|
||||
|
||||
class testcase_deadread : public testcase {
|
||||
typedef testcase inherited;
|
||||
|
||||
public:
|
||||
testcase_deadread(const actor_config &config, const mdbx_pid_t pid)
|
||||
: testcase(config, pid) {}
|
||||
bool setup();
|
||||
bool run();
|
||||
bool teardown();
|
||||
};
|
||||
|
||||
class testcase_deadwrite : public testcase {
|
||||
typedef testcase inherited;
|
||||
|
||||
public:
|
||||
testcase_deadwrite(const actor_config &config, const mdbx_pid_t pid)
|
||||
: testcase(config, pid) {}
|
||||
bool setup();
|
||||
bool run();
|
||||
bool teardown();
|
||||
};
|
||||
|
||||
class testcase_jitter : public testcase {
|
||||
typedef testcase inherited;
|
||||
|
||||
public:
|
||||
testcase_jitter(const actor_config &config, const mdbx_pid_t pid)
|
||||
: testcase(config, pid) {}
|
||||
bool setup();
|
||||
bool run();
|
||||
bool teardown();
|
||||
};
|
||||
|
||||
class testcase_try : public testcase {
|
||||
typedef testcase inherited;
|
||||
|
||||
public:
|
||||
testcase_try(const actor_config &config, const mdbx_pid_t pid)
|
||||
: testcase(config, pid) {}
|
||||
bool setup();
|
||||
bool run();
|
||||
bool teardown();
|
||||
};
|
||||
|
||||
class testcase_copy : public testcase {
|
||||
const std::string copy_pathname;
|
||||
void copy_db(const bool with_compaction);
|
||||
|
||||
public:
|
||||
testcase_copy(const actor_config &config, const mdbx_pid_t pid)
|
||||
: testcase(config, pid),
|
||||
copy_pathname(config.params.pathname_db + "-copy") {}
|
||||
bool run();
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
@@ -184,6 +184,7 @@
|
||||
<ClCompile Include="cases.cc" />
|
||||
<ClCompile Include="chrono.cc" />
|
||||
<ClCompile Include="config.cc" />
|
||||
<ClCompile Include="copy.cc" />
|
||||
<ClCompile Include="dead.cc" />
|
||||
<ClCompile Include="hill.cc" />
|
||||
<ClCompile Include="try.cc" />
|
||||
|
||||
19
test/try.cc
19
test/try.cc
@@ -1,13 +1,4 @@
|
||||
#include "test.h"
|
||||
|
||||
bool testcase_try::setup() {
|
||||
log_trace(">> setup");
|
||||
if (!inherited::setup())
|
||||
return false;
|
||||
|
||||
log_trace("<< setup");
|
||||
return true;
|
||||
}
|
||||
#include "test.h"
|
||||
|
||||
bool testcase_try::run() {
|
||||
db_open();
|
||||
@@ -27,11 +18,3 @@ bool testcase_try::run() {
|
||||
txn_guard.reset(txn);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testcase_try::teardown() {
|
||||
log_trace(">> teardown");
|
||||
cursor_guard.release();
|
||||
txn_guard.release();
|
||||
db_guard.release();
|
||||
return inherited::teardown();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user