react-native-mmkv-dz 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/LICENSE +219 -0
  2. package/MMKV/CHANGELOG.md +553 -0
  3. package/MMKV/Core/CMakeLists.txt +153 -0
  4. package/MMKV/Core/CodedInputData.cpp +228 -0
  5. package/MMKV/Core/CodedInputData.h +83 -0
  6. package/MMKV/Core/CodedInputDataCrypt.cpp +280 -0
  7. package/MMKV/Core/CodedInputDataCrypt.h +87 -0
  8. package/MMKV/Core/CodedInputDataCrypt_OSX.cpp +62 -0
  9. package/MMKV/Core/CodedInputData_OSX.cpp +92 -0
  10. package/MMKV/Core/CodedOutputData.cpp +174 -0
  11. package/MMKV/Core/CodedOutputData.h +82 -0
  12. package/MMKV/Core/Core.xcodeproj/project.pbxproj +702 -0
  13. package/MMKV/Core/Core.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  14. package/MMKV/Core/Core.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  15. package/MMKV/Core/Core.xcodeproj/xcshareddata/xcschemes/Core.xcscheme +67 -0
  16. package/MMKV/Core/Core.xcodeproj/xcshareddata/xcschemes/MMKVWatchCore.xcscheme +67 -0
  17. package/MMKV/Core/InterProcessLock.cpp +186 -0
  18. package/MMKV/Core/InterProcessLock.h +119 -0
  19. package/MMKV/Core/InterProcessLock_Android.cpp +103 -0
  20. package/MMKV/Core/InterProcessLock_Win32.cpp +108 -0
  21. package/MMKV/Core/KeyValueHolder.cpp +236 -0
  22. package/MMKV/Core/KeyValueHolder.h +118 -0
  23. package/MMKV/Core/MMBuffer.cpp +185 -0
  24. package/MMKV/Core/MMBuffer.h +107 -0
  25. package/MMKV/Core/MMKV.cpp +1418 -0
  26. package/MMKV/Core/MMKV.h +386 -0
  27. package/MMKV/Core/MMKVLog.cpp +127 -0
  28. package/MMKV/Core/MMKVLog.h +86 -0
  29. package/MMKV/Core/MMKVLog_Android.cpp +79 -0
  30. package/MMKV/Core/MMKVMetaInfo.hpp +81 -0
  31. package/MMKV/Core/MMKVPredef.h +245 -0
  32. package/MMKV/Core/MMKV_Android.cpp +259 -0
  33. package/MMKV/Core/MMKV_IO.cpp +1119 -0
  34. package/MMKV/Core/MMKV_IO.h +57 -0
  35. package/MMKV/Core/MMKV_OSX.cpp +347 -0
  36. package/MMKV/Core/MMKV_OSX.h +51 -0
  37. package/MMKV/Core/MemoryFile.cpp +537 -0
  38. package/MMKV/Core/MemoryFile.h +182 -0
  39. package/MMKV/Core/MemoryFile_Android.cpp +211 -0
  40. package/MMKV/Core/MemoryFile_Linux.cpp +120 -0
  41. package/MMKV/Core/MemoryFile_OSX.cpp +142 -0
  42. package/MMKV/Core/MemoryFile_Win32.cpp +536 -0
  43. package/MMKV/Core/MiniPBCoder.cpp +366 -0
  44. package/MMKV/Core/MiniPBCoder.h +129 -0
  45. package/MMKV/Core/MiniPBCoder_OSX.cpp +228 -0
  46. package/MMKV/Core/PBEncodeItem.hpp +86 -0
  47. package/MMKV/Core/PBUtility.cpp +61 -0
  48. package/MMKV/Core/PBUtility.h +153 -0
  49. package/MMKV/Core/ScopedLock.hpp +69 -0
  50. package/MMKV/Core/ThreadLock.cpp +68 -0
  51. package/MMKV/Core/ThreadLock.h +78 -0
  52. package/MMKV/Core/ThreadLock_Win32.cpp +89 -0
  53. package/MMKV/Core/aes/AESCrypt.cpp +256 -0
  54. package/MMKV/Core/aes/AESCrypt.h +107 -0
  55. package/MMKV/Core/aes/openssl/openssl_aes-armv4.S +1231 -0
  56. package/MMKV/Core/aes/openssl/openssl_aes.h +118 -0
  57. package/MMKV/Core/aes/openssl/openssl_aes_core.cpp +1044 -0
  58. package/MMKV/Core/aes/openssl/openssl_aes_locl.h +38 -0
  59. package/MMKV/Core/aes/openssl/openssl_aesv8-armx.S +308 -0
  60. package/MMKV/Core/aes/openssl/openssl_arm_arch.h +84 -0
  61. package/MMKV/Core/aes/openssl/openssl_cfb128.cpp +97 -0
  62. package/MMKV/Core/aes/openssl/openssl_md32_common.h +254 -0
  63. package/MMKV/Core/aes/openssl/openssl_md5.h +49 -0
  64. package/MMKV/Core/aes/openssl/openssl_md5_dgst.cpp +166 -0
  65. package/MMKV/Core/aes/openssl/openssl_md5_locl.h +75 -0
  66. package/MMKV/Core/aes/openssl/openssl_md5_one.cpp +30 -0
  67. package/MMKV/Core/aes/openssl/openssl_opensslconf.h +271 -0
  68. package/MMKV/Core/core.vcxproj +186 -0
  69. package/MMKV/Core/core.vcxproj.filters +150 -0
  70. package/MMKV/Core/crc32/Checksum.h +67 -0
  71. package/MMKV/Core/crc32/crc32_armv8.cpp +132 -0
  72. package/MMKV/Core/crc32/zlib/crc32.cpp +55 -0
  73. package/MMKV/Core/crc32/zlib/crc32.h +48 -0
  74. package/MMKV/Core/crc32/zlib/zconf.h +380 -0
  75. package/MMKV/Core/crc32/zlib/zutil.h +25 -0
  76. package/MMKV/LICENSE.TXT +193 -0
  77. package/MMKV/README.md +288 -0
  78. package/README.md +221 -0
  79. package/android/CMakeLists.txt +71 -0
  80. package/android/build.gradle +371 -0
  81. package/android/gradle.properties +4 -0
  82. package/android/src/main/AndroidManifest.xml +4 -0
  83. package/android/src/main/cpp/MmkvHostObject.cpp +302 -0
  84. package/android/src/main/cpp/MmkvHostObject.h +26 -0
  85. package/android/src/main/cpp/cpp-adapter.cpp +65 -0
  86. package/android/src/main/java/com/reactnativemmkv/MmkvModule.java +49 -0
  87. package/android/src/main/java/com/reactnativemmkv/MmkvPackage.java +26 -0
  88. package/cpp/TypedArray.cpp +341 -0
  89. package/cpp/TypedArray.h +175 -0
  90. package/ios/JSIUtils.h +50 -0
  91. package/ios/JSIUtils.mm +194 -0
  92. package/ios/Mmkv.xcodeproj/project.pbxproj +291 -0
  93. package/ios/MmkvHostObject.h +27 -0
  94. package/ios/MmkvHostObject.mm +299 -0
  95. package/ios/MmkvModule.h +5 -0
  96. package/ios/MmkvModule.mm +73 -0
  97. package/lib/commonjs/MMKV.js +146 -0
  98. package/lib/commonjs/MMKV.js.map +1 -0
  99. package/lib/commonjs/PlatformChecker.js +16 -0
  100. package/lib/commonjs/PlatformChecker.js.map +1 -0
  101. package/lib/commonjs/createMMKV.js +66 -0
  102. package/lib/commonjs/createMMKV.js.map +1 -0
  103. package/lib/commonjs/createMMKV.mock.js +40 -0
  104. package/lib/commonjs/createMMKV.mock.js.map +1 -0
  105. package/lib/commonjs/createMMKV.web.js +77 -0
  106. package/lib/commonjs/createMMKV.web.js.map +1 -0
  107. package/lib/commonjs/createTextEncoder.js +24 -0
  108. package/lib/commonjs/createTextEncoder.js.map +1 -0
  109. package/lib/commonjs/hooks.js +200 -0
  110. package/lib/commonjs/hooks.js.map +1 -0
  111. package/lib/commonjs/index.js +32 -0
  112. package/lib/commonjs/index.js.map +1 -0
  113. package/lib/module/MMKV.js +134 -0
  114. package/lib/module/MMKV.js.map +1 -0
  115. package/lib/module/PlatformChecker.js +9 -0
  116. package/lib/module/PlatformChecker.js.map +1 -0
  117. package/lib/module/createMMKV.js +55 -0
  118. package/lib/module/createMMKV.js.map +1 -0
  119. package/lib/module/createMMKV.mock.js +31 -0
  120. package/lib/module/createMMKV.mock.js.map +1 -0
  121. package/lib/module/createMMKV.web.js +67 -0
  122. package/lib/module/createMMKV.web.js.map +1 -0
  123. package/lib/module/createTextEncoder.js +17 -0
  124. package/lib/module/createTextEncoder.js.map +1 -0
  125. package/lib/module/hooks.js +181 -0
  126. package/lib/module/hooks.js.map +1 -0
  127. package/lib/module/index.js +3 -0
  128. package/lib/module/index.js.map +1 -0
  129. package/lib/typescript/MMKV.d.ts +137 -0
  130. package/lib/typescript/PlatformChecker.d.ts +1 -0
  131. package/lib/typescript/createMMKV.d.ts +6 -0
  132. package/lib/typescript/createMMKV.mock.d.ts +2 -0
  133. package/lib/typescript/createMMKV.web.d.ts +2 -0
  134. package/lib/typescript/createTextEncoder.d.ts +1 -0
  135. package/lib/typescript/hooks.d.ts +81 -0
  136. package/lib/typescript/index.d.ts +2 -0
  137. package/package.json +168 -0
  138. package/react-native-mmkv.podspec +32 -0
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Workspace
3
+ version = "1.0">
4
+ <FileRef
5
+ location = "self:Core.xcodeproj">
6
+ </FileRef>
7
+ </Workspace>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>IDEDidComputeMac32BitWarning</key>
6
+ <true/>
7
+ </dict>
8
+ </plist>
@@ -0,0 +1,67 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Scheme
3
+ LastUpgradeVersion = "1330"
4
+ version = "1.3">
5
+ <BuildAction
6
+ parallelizeBuildables = "YES"
7
+ buildImplicitDependencies = "YES">
8
+ <BuildActionEntries>
9
+ <BuildActionEntry
10
+ buildForTesting = "YES"
11
+ buildForRunning = "YES"
12
+ buildForProfiling = "YES"
13
+ buildForArchiving = "YES"
14
+ buildForAnalyzing = "YES">
15
+ <BuildableReference
16
+ BuildableIdentifier = "primary"
17
+ BlueprintIdentifier = "CB9563D723AB2D9500ACCD39"
18
+ BuildableName = "libMMKVCore.a"
19
+ BlueprintName = "MMKVCore"
20
+ ReferencedContainer = "container:Core.xcodeproj">
21
+ </BuildableReference>
22
+ </BuildActionEntry>
23
+ </BuildActionEntries>
24
+ </BuildAction>
25
+ <TestAction
26
+ buildConfiguration = "Debug"
27
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29
+ shouldUseLaunchSchemeArgsEnv = "YES">
30
+ <Testables>
31
+ </Testables>
32
+ </TestAction>
33
+ <LaunchAction
34
+ buildConfiguration = "Debug"
35
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
36
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
37
+ launchStyle = "0"
38
+ useCustomWorkingDirectory = "NO"
39
+ ignoresPersistentStateOnLaunch = "NO"
40
+ debugDocumentVersioning = "YES"
41
+ debugServiceExtension = "internal"
42
+ allowLocationSimulation = "YES">
43
+ </LaunchAction>
44
+ <ProfileAction
45
+ buildConfiguration = "Release"
46
+ shouldUseLaunchSchemeArgsEnv = "YES"
47
+ savedToolIdentifier = ""
48
+ useCustomWorkingDirectory = "NO"
49
+ debugDocumentVersioning = "YES">
50
+ <MacroExpansion>
51
+ <BuildableReference
52
+ BuildableIdentifier = "primary"
53
+ BlueprintIdentifier = "CB9563D723AB2D9500ACCD39"
54
+ BuildableName = "libMMKVCore.a"
55
+ BlueprintName = "MMKVCore"
56
+ ReferencedContainer = "container:Core.xcodeproj">
57
+ </BuildableReference>
58
+ </MacroExpansion>
59
+ </ProfileAction>
60
+ <AnalyzeAction
61
+ buildConfiguration = "Debug">
62
+ </AnalyzeAction>
63
+ <ArchiveAction
64
+ buildConfiguration = "Release"
65
+ revealArchiveInOrganizer = "YES">
66
+ </ArchiveAction>
67
+ </Scheme>
@@ -0,0 +1,67 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Scheme
3
+ LastUpgradeVersion = "1330"
4
+ version = "1.3">
5
+ <BuildAction
6
+ parallelizeBuildables = "YES"
7
+ buildImplicitDependencies = "YES">
8
+ <BuildActionEntries>
9
+ <BuildActionEntry
10
+ buildForTesting = "YES"
11
+ buildForRunning = "YES"
12
+ buildForProfiling = "YES"
13
+ buildForArchiving = "YES"
14
+ buildForAnalyzing = "YES">
15
+ <BuildableReference
16
+ BuildableIdentifier = "primary"
17
+ BlueprintIdentifier = "CBF1904E243D70BA001C82ED"
18
+ BuildableName = "libMMKVCore.a"
19
+ BlueprintName = "MMKVWatchCore"
20
+ ReferencedContainer = "container:Core.xcodeproj">
21
+ </BuildableReference>
22
+ </BuildActionEntry>
23
+ </BuildActionEntries>
24
+ </BuildAction>
25
+ <TestAction
26
+ buildConfiguration = "Debug"
27
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29
+ shouldUseLaunchSchemeArgsEnv = "YES">
30
+ <Testables>
31
+ </Testables>
32
+ </TestAction>
33
+ <LaunchAction
34
+ buildConfiguration = "Debug"
35
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
36
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
37
+ launchStyle = "0"
38
+ useCustomWorkingDirectory = "NO"
39
+ ignoresPersistentStateOnLaunch = "NO"
40
+ debugDocumentVersioning = "YES"
41
+ debugServiceExtension = "internal"
42
+ allowLocationSimulation = "YES">
43
+ </LaunchAction>
44
+ <ProfileAction
45
+ buildConfiguration = "Release"
46
+ shouldUseLaunchSchemeArgsEnv = "YES"
47
+ savedToolIdentifier = ""
48
+ useCustomWorkingDirectory = "NO"
49
+ debugDocumentVersioning = "YES">
50
+ <MacroExpansion>
51
+ <BuildableReference
52
+ BuildableIdentifier = "primary"
53
+ BlueprintIdentifier = "CBF1904E243D70BA001C82ED"
54
+ BuildableName = "libMMKVCore.a"
55
+ BlueprintName = "MMKVWatchCore"
56
+ ReferencedContainer = "container:Core.xcodeproj">
57
+ </BuildableReference>
58
+ </MacroExpansion>
59
+ </ProfileAction>
60
+ <AnalyzeAction
61
+ buildConfiguration = "Debug">
62
+ </AnalyzeAction>
63
+ <ArchiveAction
64
+ buildConfiguration = "Release"
65
+ revealArchiveInOrganizer = "YES">
66
+ </ArchiveAction>
67
+ </Scheme>
@@ -0,0 +1,186 @@
1
+ /*
2
+ * Tencent is pleased to support the open source community by making
3
+ * MMKV available.
4
+ *
5
+ * Copyright (C) 2018 THL A29 Limited, a Tencent company.
6
+ * All rights reserved.
7
+ *
8
+ * Licensed under the BSD 3-Clause License (the "License"); you may not use
9
+ * this file except in compliance with the License. You may obtain a copy of
10
+ * the License at
11
+ *
12
+ * https://opensource.org/licenses/BSD-3-Clause
13
+ *
14
+ * Unless required by applicable law or agreed to in writing, software
15
+ * distributed under the License is distributed on an "AS IS" BASIS,
16
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ * See the License for the specific language governing permissions and
18
+ * limitations under the License.
19
+ */
20
+
21
+ #include "InterProcessLock.h"
22
+ #include "MMKVLog.h"
23
+
24
+ #ifndef MMKV_WIN32
25
+ # include <sys/file.h>
26
+ #endif
27
+
28
+ namespace mmkv {
29
+
30
+ bool FileLock::lock(LockType lockType) {
31
+ return doLock(lockType, true);
32
+ }
33
+
34
+ bool FileLock::try_lock(LockType lockType, bool *tryAgain) {
35
+ return doLock(lockType, false, tryAgain);
36
+ }
37
+
38
+ bool FileLock::doLock(LockType lockType, bool wait, bool *tryAgain) {
39
+ if (!isFileLockValid()) {
40
+ return false;
41
+ }
42
+ bool unLockFirstIfNeeded = false;
43
+
44
+ if (lockType == SharedLockType) {
45
+ // don't want shared-lock to break any existing locks
46
+ if (m_sharedLockCount > 0 || m_exclusiveLockCount > 0) {
47
+ m_sharedLockCount++;
48
+ return true;
49
+ }
50
+ } else {
51
+ // don't want exclusive-lock to break existing exclusive-locks
52
+ if (m_exclusiveLockCount > 0) {
53
+ m_exclusiveLockCount++;
54
+ return true;
55
+ }
56
+ // prevent deadlock
57
+ if (m_sharedLockCount > 0) {
58
+ unLockFirstIfNeeded = true;
59
+ }
60
+ }
61
+
62
+ auto ret = platformLock(lockType, wait, unLockFirstIfNeeded, tryAgain);
63
+ if (ret) {
64
+ if (lockType == SharedLockType) {
65
+ m_sharedLockCount++;
66
+ } else {
67
+ m_exclusiveLockCount++;
68
+ }
69
+ }
70
+ return ret;
71
+ }
72
+
73
+ #ifndef MMKV_WIN32
74
+
75
+ static int32_t LockType2FlockType(LockType lockType) {
76
+ switch (lockType) {
77
+ case SharedLockType:
78
+ return LOCK_SH;
79
+ case ExclusiveLockType:
80
+ return LOCK_EX;
81
+ }
82
+ return LOCK_EX;
83
+ }
84
+
85
+ bool FileLock::platformLock(LockType lockType, bool wait, bool unLockFirstIfNeeded, bool *tryAgain) {
86
+ # ifdef MMKV_ANDROID
87
+ if (m_isAshmem) {
88
+ return ashmemLock(lockType, wait, unLockFirstIfNeeded, tryAgain);
89
+ }
90
+ # endif
91
+ auto realLockType = LockType2FlockType(lockType);
92
+ auto cmd = wait ? realLockType : (realLockType | LOCK_NB);
93
+ if (unLockFirstIfNeeded) {
94
+ // try lock
95
+ auto ret = flock(m_fd, realLockType | LOCK_NB);
96
+ if (ret == 0) {
97
+ return true;
98
+ }
99
+ // let's be gentleman: unlock my shared-lock to prevent deadlock
100
+ ret = flock(m_fd, LOCK_UN);
101
+ if (ret != 0) {
102
+ MMKVError("fail to try unlock first fd=%d, ret=%d, error:%s", m_fd, ret, strerror(errno));
103
+ }
104
+ }
105
+
106
+ auto ret = flock(m_fd, cmd);
107
+ if (ret != 0) {
108
+ if (tryAgain) {
109
+ *tryAgain = (errno == EWOULDBLOCK);
110
+ }
111
+ if (wait) {
112
+ MMKVError("fail to lock fd=%d, ret=%d, error:%s", m_fd, ret, strerror(errno));
113
+ }
114
+ // try recover my shared-lock
115
+ if (unLockFirstIfNeeded) {
116
+ ret = flock(m_fd, LockType2FlockType(SharedLockType));
117
+ if (ret != 0) {
118
+ // let's hope this never happen
119
+ MMKVError("fail to recover shared-lock fd=%d, ret=%d, error:%s", m_fd, ret, strerror(errno));
120
+ }
121
+ }
122
+ return false;
123
+ } else {
124
+ return true;
125
+ }
126
+ }
127
+
128
+ bool FileLock::platformUnLock(bool unlockToSharedLock) {
129
+ # ifdef MMKV_ANDROID
130
+ if (m_isAshmem) {
131
+ return ashmemUnLock(unlockToSharedLock);
132
+ }
133
+ # endif
134
+ int cmd = unlockToSharedLock ? LOCK_SH : LOCK_UN;
135
+ auto ret = flock(m_fd, cmd);
136
+ if (ret != 0) {
137
+ MMKVError("fail to unlock fd=%d, ret=%d, error:%s", m_fd, ret, strerror(errno));
138
+ return false;
139
+ } else {
140
+ return true;
141
+ }
142
+ }
143
+
144
+ #endif // MMKV_WIN32
145
+
146
+ bool FileLock::unlock(LockType lockType) {
147
+ if (!isFileLockValid()) {
148
+ return false;
149
+ }
150
+ bool unlockToSharedLock = false;
151
+
152
+ if (lockType == SharedLockType) {
153
+ if (m_sharedLockCount == 0) {
154
+ return false;
155
+ }
156
+ // don't want shared-lock to break any existing locks
157
+ if (m_sharedLockCount > 1 || m_exclusiveLockCount > 0) {
158
+ m_sharedLockCount--;
159
+ return true;
160
+ }
161
+ } else {
162
+ if (m_exclusiveLockCount == 0) {
163
+ return false;
164
+ }
165
+ if (m_exclusiveLockCount > 1) {
166
+ m_exclusiveLockCount--;
167
+ return true;
168
+ }
169
+ // restore shared-lock when all exclusive-locks are done
170
+ if (m_sharedLockCount > 0) {
171
+ unlockToSharedLock = true;
172
+ }
173
+ }
174
+
175
+ auto ret = platformUnLock(unlockToSharedLock);
176
+ if (ret) {
177
+ if (lockType == SharedLockType) {
178
+ m_sharedLockCount--;
179
+ } else {
180
+ m_exclusiveLockCount--;
181
+ }
182
+ }
183
+ return ret;
184
+ }
185
+
186
+ } // namespace mmkv
@@ -0,0 +1,119 @@
1
+ /*
2
+ * Tencent is pleased to support the open source community by making
3
+ * MMKV available.
4
+ *
5
+ * Copyright (C) 2018 THL A29 Limited, a Tencent company.
6
+ * All rights reserved.
7
+ *
8
+ * Licensed under the BSD 3-Clause License (the "License"); you may not use
9
+ * this file except in compliance with the License. You may obtain a copy of
10
+ * the License at
11
+ *
12
+ * https://opensource.org/licenses/BSD-3-Clause
13
+ *
14
+ * Unless required by applicable law or agreed to in writing, software
15
+ * distributed under the License is distributed on an "AS IS" BASIS,
16
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ * See the License for the specific language governing permissions and
18
+ * limitations under the License.
19
+ */
20
+
21
+ #ifndef MMKV_INTERPROCESSLOCK_H
22
+ #define MMKV_INTERPROCESSLOCK_H
23
+ #ifdef __cplusplus
24
+
25
+ # include "MMKVPredef.h"
26
+
27
+ # include <fcntl.h>
28
+
29
+ namespace mmkv {
30
+
31
+ enum LockType {
32
+ SharedLockType,
33
+ ExclusiveLockType,
34
+ };
35
+
36
+ // a recursive POSIX file-lock wrapper
37
+ // handles lock upgrade & downgrade correctly
38
+ class FileLock {
39
+ MMKVFileHandle_t m_fd;
40
+ size_t m_sharedLockCount;
41
+ size_t m_exclusiveLockCount;
42
+
43
+ bool doLock(LockType lockType, bool wait, bool *tryAgain = nullptr);
44
+ bool platformLock(LockType lockType, bool wait, bool unLockFirstIfNeeded, bool *tryAgain);
45
+ bool platformUnLock(bool unLockFirstIfNeeded);
46
+
47
+ # ifndef MMKV_WIN32
48
+ bool isFileLockValid() { return m_fd >= 0; }
49
+ # ifdef MMKV_ANDROID
50
+ const bool m_isAshmem;
51
+ struct flock m_lockInfo;
52
+ bool ashmemLock(LockType lockType, bool wait, bool unLockFirstIfNeeded, bool *tryAgain);
53
+ bool ashmemUnLock(bool unLockFirstIfNeeded);
54
+ # endif
55
+
56
+ # else // defined(MMKV_WIN32)
57
+ OVERLAPPED m_overLapped;
58
+
59
+ bool isFileLockValid() { return m_fd != INVALID_HANDLE_VALUE; }
60
+ # endif // MMKV_WIN32
61
+
62
+ public:
63
+ # ifndef MMKV_WIN32
64
+ # ifndef MMKV_ANDROID
65
+ explicit FileLock(MMKVFileHandle_t fd) : m_fd(fd), m_sharedLockCount(0), m_exclusiveLockCount(0) {}
66
+ # else
67
+ explicit FileLock(MMKVFileHandle_t fd, bool isAshmem = false);
68
+ # endif // MMKV_ANDROID
69
+ # else // defined(MMKV_WIN32)
70
+ explicit FileLock(MMKVFileHandle_t fd) : m_fd(fd), m_overLapped{}, m_sharedLockCount(0), m_exclusiveLockCount(0) {}
71
+ # endif // MMKV_WIN32
72
+
73
+ bool lock(LockType lockType);
74
+
75
+ bool try_lock(LockType lockType, bool *tryAgain);
76
+
77
+ bool unlock(LockType lockType);
78
+
79
+ // just forbid it for possibly misuse
80
+ explicit FileLock(const FileLock &other) = delete;
81
+ FileLock &operator=(const FileLock &other) = delete;
82
+ };
83
+
84
+ class InterProcessLock {
85
+ FileLock *m_fileLock;
86
+ LockType m_lockType;
87
+
88
+ public:
89
+ InterProcessLock(FileLock *fileLock, LockType lockType)
90
+ : m_fileLock(fileLock), m_lockType(lockType), m_enable(true) {
91
+ MMKV_ASSERT(m_fileLock);
92
+ }
93
+
94
+ bool m_enable;
95
+
96
+ void lock() {
97
+ if (m_enable) {
98
+ m_fileLock->lock(m_lockType);
99
+ }
100
+ }
101
+
102
+ bool try_lock(bool *tryAgain = nullptr) {
103
+ if (m_enable) {
104
+ return m_fileLock->try_lock(m_lockType, tryAgain);
105
+ }
106
+ return false;
107
+ }
108
+
109
+ void unlock() {
110
+ if (m_enable) {
111
+ m_fileLock->unlock(m_lockType);
112
+ }
113
+ }
114
+ };
115
+
116
+ } // namespace mmkv
117
+
118
+ #endif // __cplusplus
119
+ #endif // MMKV_INTERPROCESSLOCK_H
@@ -0,0 +1,103 @@
1
+ /*
2
+ * Tencent is pleased to support the open source community by making
3
+ * MMKV available.
4
+ *
5
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company.
6
+ * All rights reserved.
7
+ *
8
+ * Licensed under the BSD 3-Clause License (the "License"); you may not use
9
+ * this file except in compliance with the License. You may obtain a copy of
10
+ * the License at
11
+ *
12
+ * https://opensource.org/licenses/BSD-3-Clause
13
+ *
14
+ * Unless required by applicable law or agreed to in writing, software
15
+ * distributed under the License is distributed on an "AS IS" BASIS,
16
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ * See the License for the specific language governing permissions and
18
+ * limitations under the License.
19
+ */
20
+
21
+ #include "InterProcessLock.h"
22
+
23
+ #ifdef MMKV_ANDROID
24
+ # include "MMKVLog.h"
25
+ # include <sys/file.h>
26
+ # include <unistd.h>
27
+
28
+ namespace mmkv {
29
+
30
+ FileLock::FileLock(MMKVFileHandle_t fd, bool isAshmem)
31
+ : m_fd(fd), m_sharedLockCount(0), m_exclusiveLockCount(0), m_isAshmem(isAshmem) {
32
+ m_lockInfo.l_type = F_WRLCK;
33
+ m_lockInfo.l_start = 0;
34
+ m_lockInfo.l_whence = SEEK_SET;
35
+ m_lockInfo.l_len = 0;
36
+ m_lockInfo.l_pid = 0;
37
+ }
38
+
39
+ static short LockType2FlockType(LockType lockType) {
40
+ switch (lockType) {
41
+ case SharedLockType:
42
+ return F_RDLCK;
43
+ case ExclusiveLockType:
44
+ return F_WRLCK;
45
+ }
46
+ }
47
+
48
+ bool FileLock::ashmemLock(LockType lockType, bool wait, bool unLockFirstIfNeeded, bool *tryAgain) {
49
+ m_lockInfo.l_type = LockType2FlockType(lockType);
50
+ if (unLockFirstIfNeeded) {
51
+ // try lock
52
+ auto ret = fcntl(m_fd, F_SETLK, &m_lockInfo);
53
+ if (ret == 0) {
54
+ return true;
55
+ }
56
+ // lets be gentleman: unlock my shared-lock to prevent deadlock
57
+ auto type = m_lockInfo.l_type;
58
+ m_lockInfo.l_type = F_UNLCK;
59
+ ret = fcntl(m_fd, F_SETLK, &m_lockInfo);
60
+ if (ret != 0) {
61
+ MMKVError("fail to try unlock first fd=%d, ret=%d, error:%s", m_fd, ret, strerror(errno));
62
+ }
63
+ m_lockInfo.l_type = type;
64
+ }
65
+
66
+ int cmd = wait ? F_SETLKW : F_SETLK;
67
+ auto ret = fcntl(m_fd, cmd, &m_lockInfo);
68
+ if (ret != 0) {
69
+ if (tryAgain) {
70
+ *tryAgain = (errno == EAGAIN);
71
+ }
72
+ if (wait) {
73
+ MMKVError("fail to lock fd=%d, ret=%d, error:%s", m_fd, ret, strerror(errno));
74
+ }
75
+ // try recover my shared-lock
76
+ if (unLockFirstIfNeeded) {
77
+ m_lockInfo.l_type = LockType2FlockType(SharedLockType);
78
+ ret = fcntl(m_fd, cmd, &m_lockInfo);
79
+ if (ret != 0) {
80
+ // let's hope this never happen
81
+ MMKVError("fail to recover shared-lock fd=%d, ret=%d, error:%s", m_fd, ret, strerror(errno));
82
+ }
83
+ }
84
+ return false;
85
+ } else {
86
+ return true;
87
+ }
88
+ }
89
+
90
+ bool FileLock::ashmemUnLock(bool unlockToSharedLock) {
91
+ m_lockInfo.l_type = static_cast<short>(unlockToSharedLock ? F_RDLCK : F_UNLCK);
92
+ auto ret = fcntl(m_fd, F_SETLK, &m_lockInfo);
93
+ if (ret != 0) {
94
+ MMKVError("fail to unlock fd=%d, ret=%d, error:%s", m_fd, ret, strerror(errno));
95
+ return false;
96
+ } else {
97
+ return true;
98
+ }
99
+ }
100
+
101
+ } // namespace mmkv
102
+
103
+ #endif // MMKV_ANDROID
@@ -0,0 +1,108 @@
1
+ /*
2
+ * Tencent is pleased to support the open source community by making
3
+ * MMKV available.
4
+ *
5
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company.
6
+ * All rights reserved.
7
+ *
8
+ * Licensed under the BSD 3-Clause License (the "License"); you may not use
9
+ * this file except in compliance with the License. You may obtain a copy of
10
+ * the License at
11
+ *
12
+ * https://opensource.org/licenses/BSD-3-Clause
13
+ *
14
+ * Unless required by applicable law or agreed to in writing, software
15
+ * distributed under the License is distributed on an "AS IS" BASIS,
16
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ * See the License for the specific language governing permissions and
18
+ * limitations under the License.
19
+ */
20
+
21
+ #include "InterProcessLock.h"
22
+
23
+ #ifdef MMKV_WIN32
24
+ # include "MMKVLog.h"
25
+
26
+ namespace mmkv {
27
+
28
+ static DWORD LockType2Flag(LockType lockType) {
29
+ DWORD flag = 0;
30
+ switch (lockType) {
31
+ case SharedLockType:
32
+ flag = 0;
33
+ break;
34
+ case ExclusiveLockType:
35
+ flag = LOCKFILE_EXCLUSIVE_LOCK;
36
+ break;
37
+ }
38
+ return flag;
39
+ }
40
+
41
+ bool FileLock::platformLock(LockType lockType, bool wait, bool unLockFirstIfNeeded, bool *tryAgain) {
42
+ auto realLockType = LockType2Flag(lockType);
43
+ auto flag = wait ? realLockType : (realLockType | LOCKFILE_FAIL_IMMEDIATELY);
44
+ if (unLockFirstIfNeeded) {
45
+ /* try exclusive-lock above shared-lock will always fail in Win32
46
+ auto ret = LockFileEx(m_fd, realLockType | LOCKFILE_FAIL_IMMEDIATELY, 0, 1, 0, &m_overLapped);
47
+ if (ret) {
48
+ return true;
49
+ }*/
50
+ // let's be gentleman: unlock my shared-lock to prevent deadlock
51
+ auto ret = UnlockFileEx(m_fd, 0, 1, 0, &m_overLapped);
52
+ if (!ret) {
53
+ auto lastError = GetLastError();
54
+ if (lastError != ERROR_NOT_LOCKED) {
55
+ MMKVError("fail to try unlock first fd=%p, error:%d", m_fd, lastError);
56
+ }
57
+ }
58
+ }
59
+
60
+ auto ret = LockFileEx(m_fd, flag, 0, 1, 0, &m_overLapped);
61
+ if (!ret) {
62
+ if (tryAgain) {
63
+ *tryAgain = (GetLastError() == ERROR_LOCK_VIOLATION);
64
+ }
65
+ if (wait) {
66
+ MMKVError("fail to lock fd=%p, error:%d", m_fd, GetLastError());
67
+ }
68
+ // try recover my shared-lock
69
+ if (unLockFirstIfNeeded) {
70
+ ret = LockFileEx(m_fd, LockType2Flag(SharedLockType), 0, 1, 0, &m_overLapped);
71
+ if (!ret) {
72
+ // let's hope this never happen
73
+ MMKVError("fail to recover shared-lock fd=%p, error:%d", m_fd, GetLastError());
74
+ }
75
+ }
76
+ return false;
77
+ } else {
78
+ return true;
79
+ }
80
+ }
81
+
82
+ bool FileLock::platformUnLock(bool unlockToSharedLock) {
83
+ /* quote from MSDN:
84
+ * If the same range is locked with an exclusive and a shared lock,
85
+ * two unlock operations are necessary to unlock the region;
86
+ * the first unlock operation unlocks the exclusive lock,
87
+ * the second unlock operation unlocks the shared lock.
88
+ */
89
+ if (unlockToSharedLock) {
90
+ auto flag = LockType2Flag(SharedLockType);
91
+ if (!LockFileEx(m_fd, flag, 0, 1, 0, &m_overLapped)) {
92
+ MMKVError("fail to roll back to shared-lock, error:%d", GetLastError());
93
+ }
94
+ }
95
+ auto ret = UnlockFileEx(m_fd, 0, 1, 0, &m_overLapped);
96
+ if (!ret) {
97
+ auto lastError = GetLastError();
98
+ if (lastError != ERROR_NOT_LOCKED) {
99
+ MMKVError("fail to unlock fd=%p, error:%d", m_fd, lastError);
100
+ return false;
101
+ }
102
+ }
103
+ return true;
104
+ }
105
+
106
+ } // namespace mmkv
107
+
108
+ #endif // MMKV_WIN32