Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 74 additions & 49 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Typecheck files
run: yarn typecheck

test-ios:
ios:
runs-on: macos-latest
steps:
- name: Checkout
Expand Down Expand Up @@ -56,7 +56,7 @@ jobs:
run: |
./scripts/test-ios.sh

test-ios-embedded:
ios-embedded:
runs-on: macos-latest
steps:
- name: Checkout
Expand Down Expand Up @@ -98,7 +98,7 @@ jobs:
run: |
./scripts/test-ios.sh

test-ios-sqlcipher:
ios-sqlcipher:
runs-on: macos-latest
steps:
- name: Checkout
Expand Down Expand Up @@ -140,7 +140,7 @@ jobs:
run: |
./scripts/test-ios.sh

test-ios-libsql:
ios-libsql:
runs-on: macos-latest
steps:
- name: Checkout
Expand All @@ -149,7 +149,7 @@ jobs:
- name: Xcode Select
run: sudo xcode-select -s /Applications/Xcode_16.4.app

- name: Turn on SQLCipher
- name: Turn on libsql
run: |
node ./scripts/turnOnLibsql.js

Expand Down Expand Up @@ -182,25 +182,25 @@ jobs:
run: |
./scripts/test-ios.sh

test-android:
android:
runs-on: ubuntu-latest
timeout-minutes: 20
timeout-minutes: 40
steps:
- name: Free Disk Space (Ubuntu)
uses: insightsengineering/disk-space-reclaimer@v1
with:
# this might remove tools that are actually needed,
# if set to "true" but frees about 6 GB
tools-cache: false

# all of these default to true, but feel free to set to
# "false" if necessary for your workflow
android: false
dotnet: true
haskell: true
large-packages: true
swap-storage: true
docker-images: true
# - name: Free Disk Space (Ubuntu)
# uses: insightsengineering/disk-space-reclaimer@v1
# with:
# # this might remove tools that are actually needed,
# # if set to "true" but frees about 6 GB
# tools-cache: false

# # all of these default to true, but feel free to set to
# # "false" if necessary for your workflow
# android: false
# dotnet: true
# haskell: true
# large-packages: true
# swap-storage: true
# docker-images: true

- name: Checkout
uses: actions/checkout@v4
Expand Down Expand Up @@ -236,15 +236,15 @@ jobs:
# ~/.android/adb*
# key: avd-29

- name: create AVD and generate snapshot for caching
# if: steps.avd-cache.outputs.cache-hit != 'true'
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 29
force-avd-creation: false
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: false
script: echo "Generated AVD snapshot for caching."
# - name: create AVD and generate snapshot for caching
# # if: steps.avd-cache.outputs.cache-hit != 'true'
# uses: reactivecircus/android-emulator-runner@v2
# with:
# api-level: 29
# force-avd-creation: false
# emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
# disable-animations: false
# script: echo "Generated AVD snapshot for caching."

- name: Give execute permissions to script
run: chmod +x ./scripts/test-android.sh
Expand All @@ -259,25 +259,33 @@ jobs:
script: |
./scripts/test-android.sh

test-android-sqlcipher:
- name: Upload Android diagnostics
if: failure()
uses: actions/upload-artifact@v4
with:
name: android-logcat-${{ github.job }}
path: example/android-logcat.txt
if-no-files-found: ignore

android-sqlcipher:
runs-on: ubuntu-latest
timeout-minutes: 20
timeout-minutes: 40
steps:
- name: Free Disk Space (Ubuntu)
uses: insightsengineering/disk-space-reclaimer@v1
with:
# this might remove tools that are actually needed,
# if set to "true" but frees about 6 GB
tools-cache: false

# all of these default to true, but feel free to set to
# "false" if necessary for your workflow
android: false
dotnet: true
haskell: true
large-packages: true
swap-storage: true
docker-images: true
# - name: Free Disk Space (Ubuntu)
# uses: insightsengineering/disk-space-reclaimer@v1
# with:
# # this might remove tools that are actually needed,
# # if set to "true" but frees about 6 GB
# tools-cache: false

# # all of these default to true, but feel free to set to
# # "false" if necessary for your workflow
# android: false
# dotnet: true
# haskell: true
# large-packages: true
# swap-storage: true
# docker-images: true
- name: Checkout
uses: actions/checkout@v4

Expand Down Expand Up @@ -337,8 +345,17 @@ jobs:
adb shell input keyevent 82
./scripts/test-android.sh

test-android-libsql:
- name: Upload Android diagnostics
if: failure()
uses: actions/upload-artifact@v4
with:
name: android-logcat-${{ github.job }}
path: example/android-logcat.txt
if-no-files-found: ignore

android-libsql:
runs-on: ubuntu-latest
timeout-minutes: 40
env:
TURBO_CACHE_DIR: .turbo/android
steps:
Expand Down Expand Up @@ -387,3 +404,11 @@ jobs:
adb wait-for-device
adb shell input keyevent 82
./scripts/test-android.sh

- name: Upload Android diagnostics
if: failure()
uses: actions/upload-artifact@v4
with:
name: android-logcat-${{ github.job }}
path: example/android-logcat.txt
if-no-files-found: ignore
15 changes: 13 additions & 2 deletions cpp/DBHostObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,16 @@ void DBHostObject::create_jsi_functions(jsi::Runtime &rt) {

function_map["close"] = HFN(this) {
invalidated = true;

// Drain any in-flight async queries before closing the db handle.
// Without this, a queued/running execute() on the thread pool may
// dereference the freed sqlite3* pointer → heap corruption / SIGABRT.
thread_pool->waitFinished();
#ifdef OP_SQLITE_USE_LIBSQL
opsqlite_libsql_close(db);
db = {};
#else
opsqlite_close(db);
db = nullptr;
#endif

return {};
Expand Down Expand Up @@ -671,7 +676,13 @@ void DBHostObject::invalidate() {
}

invalidated = true;
thread_pool->restartPool();
// Drain in-flight thread pool work before closing the db handle.
// restartPool() joins threads (waiting for the current task) but then
// needlessly re-creates the pool. waitFinished() is sufficient: it
// blocks until the queue is empty and no worker is busy, then the
// ThreadPool destructor (via shared_ptr release) joins the threads.
thread_pool->waitFinished();

#ifdef OP_SQLITE_USE_LIBSQL
opsqlite_libsql_close(db);
#else
Expand Down
8 changes: 6 additions & 2 deletions cpp/OPThreadPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,14 @@ void ThreadPool::doWork() {

task = workQueue.front();
workQueue.pop();
++busy;
}
++busy;
task();
--busy;
{
std::lock_guard<std::mutex> g(workQueueMutex);
--busy;
}
workQueueConditionVariable.notify_one();
}
}

Expand Down
28 changes: 1 addition & 27 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,6 @@ PODS:
- ReactCommon/turbomodule/core
- ReactNativeDependencies
- Yoga
- OpServer (0.1.5):
- hermes-engine
- RCTRequired
- RCTTypeSafety
- React-Core
- React-Core-prebuilt
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-jsi
- React-NativeModulesApple
- React-RCTFabric
- React-renderercss
- React-rendererdebug
- React-utils
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- ReactNativeDependencies
- Yoga
- RCTDeprecation (0.82.1)
- RCTRequired (0.82.1)
- RCTTypeSafety (0.82.1):
Expand Down Expand Up @@ -1803,7 +1781,6 @@ DEPENDENCIES:
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
- hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
- op-sqlite (from `../..`)
- "OpServer (from `../node_modules/@op-engineering/op-server`)"
- RCTDeprecation (from `../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`)
- RCTRequired (from `../node_modules/react-native/Libraries/Required`)
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
Expand Down Expand Up @@ -1883,8 +1860,6 @@ EXTERNAL SOURCES:
:tag: hermes-2025-09-01-RNv0.82.0-265ef62ff3eb7289d17e366664ac0da82303e101
op-sqlite:
:path: "../.."
OpServer:
:path: "../node_modules/@op-engineering/op-server"
RCTDeprecation:
:path: "../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation"
RCTRequired:
Expand Down Expand Up @@ -2027,8 +2002,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
FBLazyVector: 2e5b5553df729e080483373db6f045201ff4e6db
hermes-engine: 273e30e7fb618279934b0b95ffab60ecedb7acf5
op-sqlite: a0d8cbee3fc5f8c8b67272c3b07c3b4f07b5b17f
OpServer: 9b3ebdeeb095950e760e3c39853cd06849421b35
op-sqlite: e13a2ee437f845fb06f24809f3b2299aa1ef9d0b
RCTDeprecation: c6b36da89aa26090c8684d29c2868dcca2cd4554
RCTRequired: 1413a0844770d00fa1f1bb2da4680adfa8698065
RCTTypeSafety: 354b4bb344998550c45d054ef66913837948f958
Expand Down
3 changes: 2 additions & 1 deletion example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"ios": "react-native run-ios --scheme='debug' --simulator='iPhone 16 Pro'",
"run:ios:unused": "xcodebuild -workspace ios/OPSQLiteExample.xcworkspace -scheme release -configuration Release -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 16 Pro' clean build",
"run:ios:release": "react-native run-ios --scheme='release' --no-packager",
"postinstall": "patch-package",
"start": "react-native start",
"pods": "cd ios && bundle exec pod install && rm -f .xcode.env.local",
"pods:nuke": "cd ios && rm -rf Pods && rm -rf Podfile.lock && bundle exec pod install",
Expand All @@ -15,7 +16,6 @@
"build:ios": "cd ios && xcodebuild -workspace OPSQLiteExample.xcworkspace -scheme debug -configuration Debug -sdk iphonesimulator CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ GCC_OPTIMIZATION_LEVEL=0 GCC_PRECOMPILE_PREFIX_HEADER=YES ASSETCATALOG_COMPILER_OPTIMIZATION=time DEBUG_INFORMATION_FORMAT=dwarf COMPILER_INDEX_STORE_ENABLE=NO"
},
"dependencies": {
"@op-engineering/op-server": "^0.1.5",
"@op-engineering/op-test": "^0.2.5",
"chance": "^1.1.9",
"clsx": "^2.0.0",
Expand All @@ -36,6 +36,7 @@
"@react-native/typescript-config": "0.81.5",
"@types/chance": "^1.1.7",
"@types/react": "^19.1.1",
"patch-package": "^8.0.1",
"react-native-builder-bob": "^0.40.13",
"react-native-monorepo-config": "^0.1.9",
"react-native-restart": "^0.0.27",
Expand Down
Loading
Loading