1 /*
2 * fdbJNI.cpp
3 *
4 * This source file is part of the FoundationDB open source project
5 *
6 * Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
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 <jni.h>
22 #include <string.h>
23
24 #define FDB_API_VERSION 610
25
26 #include <foundationdb/fdb_c.h>
27
28 #define JNI_NULL nullptr
29
30 #if defined(__GNUG__)
31 #define thread_local __thread
32 // TODO: figure out why the default definition suppresses visibility
33 #undef JNIEXPORT
34 #define JNIEXPORT __attribute__ ((visibility ("default")))
35 #elif defined(_MSC_VER)
36 #define thread_local __declspec(thread)
37 #else
38 #error Missing thread local storage
39 #endif
40
41 static JavaVM* g_jvm = nullptr;
42 static thread_local JNIEnv* g_thread_jenv = nullptr; // Defined for the network thread once it is running, and for any thread that has called registerCallback
43 static thread_local jmethodID g_IFutureCallback_call_methodID = JNI_NULL;
44 static thread_local bool is_external = false;
45
detachIfExternalThread(void * ignore)46 void detachIfExternalThread(void *ignore) {
47 if(is_external && g_thread_jenv != nullptr) {
48 g_thread_jenv = nullptr;
49 g_IFutureCallback_call_methodID = JNI_NULL;
50 g_jvm->DetachCurrentThread();
51 }
52 }
53
throwOutOfMem(JNIEnv * jenv)54 void throwOutOfMem(JNIEnv *jenv) {
55 const char *className = "java/lang/OutOfMemoryError";
56 jclass illegalArgClass = jenv->FindClass( className );
57
58 if(jenv->ExceptionOccurred())
59 return;
60
61 if( jenv->ThrowNew( illegalArgClass, nullptr ) != 0 ) {
62 if( !jenv->ExceptionOccurred() ) {
63 jenv->FatalError("Could not throw OutOfMemoryError");
64 } else {
65 // This means that an exception is pending. We do not know what it is, but are sure
66 // that control flow will include throwing that exception into the calling Java code.
67 }
68 }
69 }
70
getThrowable(JNIEnv * jenv,fdb_error_t e,const char * msg=nullptr)71 static jthrowable getThrowable(JNIEnv *jenv, fdb_error_t e, const char* msg = nullptr) {
72 jclass excepClass = jenv->FindClass("com/apple/foundationdb/FDBException");
73 if(jenv->ExceptionOccurred())
74 return JNI_NULL;
75
76 jmethodID excepCtor = jenv->GetMethodID(excepClass, "<init>", "(Ljava/lang/String;I)V");
77 if(jenv->ExceptionOccurred())
78 return JNI_NULL;
79
80 const char *fdb_message = msg ? msg : fdb_get_error(e);
81 jstring m = jenv->NewStringUTF(fdb_message);
82 if(jenv->ExceptionOccurred())
83 return JNI_NULL;
84
85 jthrowable t = (jthrowable)jenv->NewObject(excepClass, excepCtor, m, e);
86 if(jenv->ExceptionOccurred())
87 return JNI_NULL;
88
89 return t;
90 }
91
throwNamedException(JNIEnv * jenv,const char * class_full_name,const char * message)92 void throwNamedException(JNIEnv *jenv, const char *class_full_name, const char* message ) {
93 jclass exceptionClass = jenv->FindClass( class_full_name );
94 if(jenv->ExceptionOccurred())
95 return;
96
97 if( jenv->ThrowNew( exceptionClass, message ) != 0 ) {
98 if(jenv->ExceptionOccurred())
99 return;
100 jenv->FatalError("FDB: Error throwing exception");
101 }
102 }
103
throwRuntimeEx(JNIEnv * jenv,const char * message)104 void throwRuntimeEx(JNIEnv *jenv, const char* message) {
105 throwNamedException( jenv, "java/lang/RuntimeException", message );
106 }
107
throwParamNotNull(JNIEnv * jenv)108 void throwParamNotNull(JNIEnv *jenv) {
109 throwNamedException( jenv, "java/lang/IllegalArgumentException", "Argument cannot be null" );
110 }
111
112 #ifdef __cplusplus
113 extern "C" {
114 #endif
115
116 // If the methods are not found, exceptions are thrown and this will return false.
117 // Returns TRUE on success, false otherwise.
findCallbackMethods(JNIEnv * jenv)118 static bool findCallbackMethods(JNIEnv *jenv) {
119 jclass cls = jenv->FindClass("java/lang/Runnable");
120 if(jenv->ExceptionOccurred())
121 return false;
122
123 g_IFutureCallback_call_methodID = jenv->GetMethodID(cls, "run", "()V");
124 if(jenv->ExceptionOccurred())
125 return false;
126
127 return true;
128 }
129
callCallback(FDBFuture * f,void * data)130 static void callCallback( FDBFuture* f, void* data ) {
131 if (g_thread_jenv == nullptr) {
132 // We are on an external thread and must attach to the JVM.
133 // The shutdown hook will later detach this thread.
134 is_external = true;
135 if( g_jvm != nullptr && g_jvm->AttachCurrentThreadAsDaemon((void **) &g_thread_jenv, nullptr) == JNI_OK ) {
136 if( !findCallbackMethods( g_thread_jenv ) ) {
137 g_thread_jenv->FatalError("FDB: Could not find callback method.\n");
138 }
139 } else {
140 // Can't call FatalError, because we don't have a pointer to the jenv...
141 // There will be a segmentation fault from the attempt to call the callback method.
142 fprintf(stderr, "FDB: Could not attach external client thread to the JVM as daemon.\n");
143 }
144 }
145
146 jobject callback = (jobject)data;
147 g_thread_jenv->CallVoidMethod( callback, g_IFutureCallback_call_methodID );
148 g_thread_jenv->DeleteGlobalRef(callback);
149 }
150
151 // Attempts to throw 't', attempts to shut down the JVM if this fails.
safeThrow(JNIEnv * jenv,jthrowable t)152 void safeThrow( JNIEnv *jenv, jthrowable t ) {
153 if( jenv->Throw( t ) != 0 ) {
154 jenv->FatalError("FDB: Unable to throw exception");
155 }
156 }
157
Java_com_apple_foundationdb_NativeFuture_Future_1registerCallback(JNIEnv * jenv,jobject cls,jlong future,jobject callback)158 JNIEXPORT void JNICALL Java_com_apple_foundationdb_NativeFuture_Future_1registerCallback(JNIEnv *jenv, jobject cls, jlong future, jobject callback) {
159 // SOMEDAY: Do this on module load instead. Can we cache method ids across threads?
160 if( !g_IFutureCallback_call_methodID ) {
161 if( !findCallbackMethods( jenv ) ) {
162 return;
163 }
164 }
165
166 if( !future || !callback ) {
167 throwParamNotNull(jenv);
168 return;
169 }
170 FDBFuture *f = (FDBFuture *)future;
171
172 // This is documented as not throwing, but simply returning null on OOM.
173 // As belt and suspenders, we will check for pending exceptions and then,
174 // if there are none and the result is null, we'll throw our own OOM.
175 callback = jenv->NewGlobalRef( callback );
176 if( !callback ) {
177 if( !jenv->ExceptionOccurred() )
178 throwOutOfMem(jenv);
179 return;
180 }
181
182 // Here we cache a thread-local reference to jenv
183 g_thread_jenv = jenv;
184 fdb_error_t err = fdb_future_set_callback( f, &callCallback, callback );
185 if( err ) {
186 jenv->DeleteGlobalRef( callback );
187 safeThrow( jenv, getThrowable( jenv, err ) );
188 }
189 }
190
Java_com_apple_foundationdb_NativeFuture_Future_1blockUntilReady(JNIEnv * jenv,jobject,jlong future)191 JNIEXPORT void JNICALL Java_com_apple_foundationdb_NativeFuture_Future_1blockUntilReady(JNIEnv *jenv, jobject, jlong future) {
192 if( !future ) {
193 throwParamNotNull(jenv);
194 return;
195 }
196 FDBFuture *sav = (FDBFuture *)future;
197
198 fdb_error_t err = fdb_future_block_until_ready( sav );
199 if( err )
200 safeThrow( jenv, getThrowable( jenv, err ) );
201 }
202
Java_com_apple_foundationdb_NativeFuture_Future_1getError(JNIEnv * jenv,jobject,jlong future)203 JNIEXPORT jthrowable JNICALL Java_com_apple_foundationdb_NativeFuture_Future_1getError(JNIEnv *jenv, jobject, jlong future) {
204 if( !future ) {
205 throwParamNotNull(jenv);
206 return JNI_NULL;
207 }
208 FDBFuture *sav = (FDBFuture *)future;
209 fdb_error_t err = fdb_future_get_error( sav );
210 if( err )
211 return getThrowable( jenv, err );
212 else
213 return JNI_NULL;
214 }
215
Java_com_apple_foundationdb_NativeFuture_Future_1isReady(JNIEnv * jenv,jobject,jlong future)216 JNIEXPORT jboolean JNICALL Java_com_apple_foundationdb_NativeFuture_Future_1isReady(JNIEnv *jenv, jobject, jlong future) {
217 if( !future ) {
218 throwParamNotNull(jenv);
219 return JNI_FALSE;
220 }
221 FDBFuture *var = (FDBFuture *)future;
222 return (jboolean)fdb_future_is_ready(var);
223 }
224
Java_com_apple_foundationdb_NativeFuture_Future_1dispose(JNIEnv * jenv,jobject,jlong future)225 JNIEXPORT void JNICALL Java_com_apple_foundationdb_NativeFuture_Future_1dispose(JNIEnv *jenv, jobject, jlong future) {
226 if( !future ) {
227 throwParamNotNull(jenv);
228 return;
229 }
230 FDBFuture *var = (FDBFuture *)future;
231 fdb_future_destroy(var);
232 }
233
Java_com_apple_foundationdb_NativeFuture_Future_1cancel(JNIEnv * jenv,jobject,jlong future)234 JNIEXPORT void JNICALL Java_com_apple_foundationdb_NativeFuture_Future_1cancel(JNIEnv *jenv, jobject, jlong future) {
235 if( !future ) {
236 throwParamNotNull(jenv);
237 return;
238 }
239 FDBFuture *var = (FDBFuture *)future;
240 fdb_future_cancel(var);
241 }
242
Java_com_apple_foundationdb_NativeFuture_Future_1releaseMemory(JNIEnv * jenv,jobject,jlong future)243 JNIEXPORT void JNICALL Java_com_apple_foundationdb_NativeFuture_Future_1releaseMemory(JNIEnv *jenv, jobject, jlong future) {
244 if( !future ) {
245 throwParamNotNull(jenv);
246 return;
247 }
248 FDBFuture *var = (FDBFuture *)future;
249 fdb_future_release_memory(var);
250 }
251
Java_com_apple_foundationdb_FutureVersion_FutureVersion_1get(JNIEnv * jenv,jobject,jlong future)252 JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FutureVersion_FutureVersion_1get(JNIEnv *jenv, jobject, jlong future) {
253 if( !future ) {
254 throwParamNotNull(jenv);
255 return 0;
256 }
257 FDBFuture *f = (FDBFuture *)future;
258
259 int64_t version = 0;
260 fdb_error_t err = fdb_future_get_version(f, &version);
261 if( err ) {
262 safeThrow( jenv, getThrowable( jenv, err ) );
263 return 0;
264 }
265
266 return (jlong)version;
267 }
268
Java_com_apple_foundationdb_FutureStrings_FutureStrings_1get(JNIEnv * jenv,jobject,jlong future)269 JNIEXPORT jobject JNICALL Java_com_apple_foundationdb_FutureStrings_FutureStrings_1get(JNIEnv *jenv, jobject, jlong future) {
270 if( !future ) {
271 throwParamNotNull(jenv);
272 return JNI_NULL;
273 }
274 FDBFuture *f = (FDBFuture *)future;
275
276 const char **strings;
277 int count;
278 fdb_error_t err = fdb_future_get_string_array( f, &strings, &count );
279 if( err ) {
280 safeThrow( jenv, getThrowable( jenv, err ) );
281 return JNI_NULL;
282 }
283
284 jclass str_clazz = jenv->FindClass("java/lang/String");
285 if( jenv->ExceptionOccurred() )
286 return JNI_NULL;
287 jobjectArray arr = jenv->NewObjectArray(count, str_clazz, JNI_NULL);
288 if( !arr ) {
289 if( !jenv->ExceptionOccurred() )
290 throwOutOfMem(jenv);
291 return JNI_NULL;
292 }
293
294 for(int i = 0; i < count; i++) {
295 jstring str = jenv->NewStringUTF( strings[i] );
296 if( !str ) {
297 if( !jenv->ExceptionOccurred() )
298 throwOutOfMem(jenv);
299 return JNI_NULL;
300 }
301
302 jenv->SetObjectArrayElement( arr, i, str );
303 if( jenv->ExceptionOccurred() )
304 return JNI_NULL;
305 }
306
307 return arr;
308 }
309
Java_com_apple_foundationdb_FutureResults_FutureResults_1getSummary(JNIEnv * jenv,jobject,jlong future)310 JNIEXPORT jobject JNICALL Java_com_apple_foundationdb_FutureResults_FutureResults_1getSummary(JNIEnv *jenv, jobject, jlong future) {
311 if( !future ) {
312 throwParamNotNull(jenv);
313 return JNI_NULL;
314 }
315
316 jclass resultCls = jenv->FindClass("com/apple/foundationdb/RangeResultSummary");
317 if( jenv->ExceptionOccurred() )
318 return JNI_NULL;
319 jmethodID resultCtorId = jenv->GetMethodID(resultCls, "<init>", "([BIZ)V");
320 if( jenv->ExceptionOccurred() )
321 return JNI_NULL;
322
323 FDBFuture *f = (FDBFuture *)future;
324
325 const FDBKeyValue *kvs;
326 int count;
327 fdb_bool_t more;
328 fdb_error_t err = fdb_future_get_keyvalue_array( f, &kvs, &count, &more );
329 if( err ) {
330 safeThrow( jenv, getThrowable( jenv, err ) );
331 return JNI_NULL;
332 }
333
334 jbyteArray lastKey = JNI_NULL;
335 if(count) {
336 lastKey = jenv->NewByteArray(kvs[count - 1].key_length);
337 if( !lastKey ) {
338 if( !jenv->ExceptionOccurred() )
339 throwOutOfMem(jenv);
340 return JNI_NULL;
341 }
342
343 jenv->SetByteArrayRegion(lastKey, 0, kvs[count - 1].key_length, (jbyte *)kvs[count - 1].key);
344 }
345
346 jobject result = jenv->NewObject(resultCls, resultCtorId, lastKey, count, (jboolean)more);
347 if( jenv->ExceptionOccurred() )
348 return JNI_NULL;
349
350 return result;
351 }
352
353 // SOMEDAY: explore doing this more efficiently with Direct ByteBuffers
Java_com_apple_foundationdb_FutureResults_FutureResults_1get(JNIEnv * jenv,jobject,jlong future)354 JNIEXPORT jobject JNICALL Java_com_apple_foundationdb_FutureResults_FutureResults_1get(JNIEnv *jenv, jobject, jlong future) {
355 if( !future ) {
356 throwParamNotNull(jenv);
357 return JNI_NULL;
358 }
359
360 jclass resultCls = jenv->FindClass("com/apple/foundationdb/RangeResult");
361 jmethodID resultCtorId = jenv->GetMethodID(resultCls, "<init>", "([B[IZ)V");
362
363 FDBFuture *f = (FDBFuture *)future;
364
365 const FDBKeyValue *kvs;
366 int count;
367 fdb_bool_t more;
368 fdb_error_t err = fdb_future_get_keyvalue_array( f, &kvs, &count, &more );
369 if( err ) {
370 safeThrow( jenv, getThrowable( jenv, err ) );
371 return JNI_NULL;
372 }
373
374 int totalKeyValueSize = 0;
375 for(int i = 0; i < count; i++) {
376 totalKeyValueSize += kvs[i].key_length + kvs[i].value_length;
377 }
378
379 jbyteArray keyValueArray = jenv->NewByteArray(totalKeyValueSize);
380 if( !keyValueArray ) {
381 if( !jenv->ExceptionOccurred() )
382 throwOutOfMem(jenv);
383 return JNI_NULL;
384 }
385 uint8_t *keyvalues_barr = (uint8_t *)jenv->GetByteArrayElements(keyValueArray, JNI_NULL);
386 if (!keyvalues_barr) {
387 throwRuntimeEx( jenv, "Error getting handle to native resources" );
388 return JNI_NULL;
389 }
390
391 jintArray lengthArray = jenv->NewIntArray(count * 2);
392 if( !lengthArray ) {
393 if( !jenv->ExceptionOccurred() )
394 throwOutOfMem(jenv);
395
396 jenv->ReleaseByteArrayElements(keyValueArray, (jbyte *)keyvalues_barr, 0);
397 return JNI_NULL;
398 }
399
400 jint *length_barr = jenv->GetIntArrayElements(lengthArray, JNI_NULL);
401 if( !length_barr ) {
402 if( !jenv->ExceptionOccurred() )
403 throwOutOfMem(jenv);
404
405 jenv->ReleaseByteArrayElements(keyValueArray, (jbyte *)keyvalues_barr, 0);
406 return JNI_NULL;
407 }
408
409 int offset = 0;
410 for(int i = 0; i < count; i++) {
411 memcpy(keyvalues_barr + offset, kvs[i].key, kvs[i].key_length);
412 length_barr[ i * 2 ] = kvs[i].key_length;
413 offset += kvs[i].key_length;
414
415 memcpy(keyvalues_barr + offset, kvs[i].value, kvs[i].value_length);
416 length_barr[ (i * 2) + 1 ] = kvs[i].value_length;
417 offset += kvs[i].value_length;
418 }
419
420 jenv->ReleaseByteArrayElements(keyValueArray, (jbyte *)keyvalues_barr, 0);
421 jenv->ReleaseIntArrayElements(lengthArray, length_barr, 0);
422
423 jobject result = jenv->NewObject(resultCls, resultCtorId, keyValueArray, lengthArray, (jboolean)more);
424 if( jenv->ExceptionOccurred() )
425 return JNI_NULL;
426
427 return result;
428 }
429
430 // SOMEDAY: explore doing this more efficiently with Direct ByteBuffers
Java_com_apple_foundationdb_FutureResult_FutureResult_1get(JNIEnv * jenv,jobject,jlong future)431 JNIEXPORT jbyteArray JNICALL Java_com_apple_foundationdb_FutureResult_FutureResult_1get(JNIEnv *jenv, jobject, jlong future) {
432 if( !future ) {
433 throwParamNotNull(jenv);
434 return JNI_NULL;
435 }
436 FDBFuture *f = (FDBFuture *)future;
437
438 fdb_bool_t present;
439 const uint8_t *value;
440 int length;
441 fdb_error_t err = fdb_future_get_value(f, &present, &value, &length);
442 if( err ) {
443 safeThrow( jenv, getThrowable( jenv, err ) );
444 return JNI_NULL;
445 }
446
447 if( !present )
448 return JNI_NULL;
449
450 jbyteArray result = jenv->NewByteArray(length);
451 if( !result ) {
452 if( !jenv->ExceptionOccurred() )
453 throwOutOfMem(jenv);
454 return JNI_NULL;
455 }
456
457 jenv->SetByteArrayRegion(result, 0, length, (const jbyte *)value);
458 return result;
459 }
460
Java_com_apple_foundationdb_FutureKey_FutureKey_1get(JNIEnv * jenv,jclass,jlong future)461 JNIEXPORT jbyteArray JNICALL Java_com_apple_foundationdb_FutureKey_FutureKey_1get(JNIEnv * jenv, jclass, jlong future) {
462 if( !future ) {
463 throwParamNotNull(jenv);
464 return JNI_NULL;
465 }
466 FDBFuture *f = (FDBFuture *)future;
467
468 const uint8_t *value;
469 int length;
470 fdb_error_t err = fdb_future_get_key(f, &value, &length);
471 if( err ) {
472 safeThrow( jenv, getThrowable( jenv, err ) );
473 return JNI_NULL;
474 }
475
476 jbyteArray result = jenv->NewByteArray(length);
477 if( !result ) {
478 if( !jenv->ExceptionOccurred() )
479 throwOutOfMem(jenv);
480 return JNI_NULL;
481 }
482
483 jenv->SetByteArrayRegion(result, 0, length, (const jbyte *)value);
484 return result;
485 }
486
Java_com_apple_foundationdb_FDBDatabase_Database_1createTransaction(JNIEnv * jenv,jobject,jlong dbPtr)487 JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FDBDatabase_Database_1createTransaction(JNIEnv *jenv, jobject, jlong dbPtr) {
488 if( !dbPtr ) {
489 throwParamNotNull(jenv);
490 return 0;
491 }
492 FDBDatabase *database = (FDBDatabase *)dbPtr;
493 FDBTransaction *tr;
494 fdb_error_t err = fdb_database_create_transaction(database, &tr);
495 if( err ) {
496 safeThrow( jenv, getThrowable( jenv, err ) );
497 return 0;
498 }
499 return (jlong)tr;
500 }
501
Java_com_apple_foundationdb_FDBDatabase_Database_1dispose(JNIEnv * jenv,jobject,jlong dPtr)502 JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBDatabase_Database_1dispose(JNIEnv *jenv, jobject, jlong dPtr) {
503 if( !dPtr ) {
504 throwParamNotNull(jenv);
505 return;
506 }
507 fdb_database_destroy( (FDBDatabase *)dPtr );
508 }
509
Java_com_apple_foundationdb_FDBDatabase_Database_1setOption(JNIEnv * jenv,jobject,jlong dPtr,jint code,jbyteArray value)510 JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBDatabase_Database_1setOption(JNIEnv *jenv, jobject, jlong dPtr, jint code, jbyteArray value) {
511 if( !dPtr ) {
512 throwParamNotNull(jenv);
513 return;
514 }
515 FDBDatabase *c = (FDBDatabase *)dPtr;
516 uint8_t *barr = nullptr;
517 int size = 0;
518
519 if(value != JNI_NULL) {
520 barr = (uint8_t *)jenv->GetByteArrayElements( value, JNI_NULL );
521 if (!barr) {
522 throwRuntimeEx( jenv, "Error getting handle to native resources" );
523 return;
524 }
525 size = jenv->GetArrayLength( value );
526 }
527 fdb_error_t err = fdb_database_set_option( c, (FDBDatabaseOption)code, barr, size );
528 if(value != JNI_NULL)
529 jenv->ReleaseByteArrayElements( value, (jbyte *)barr, JNI_ABORT );
530 if( err ) {
531 safeThrow( jenv, getThrowable( jenv, err ) );
532 }
533 }
534
Java_com_apple_foundationdb_FDB_Error_1predicate(JNIEnv * jenv,jobject,jint predicate,jint code)535 JNIEXPORT jboolean JNICALL Java_com_apple_foundationdb_FDB_Error_1predicate(JNIEnv *jenv, jobject, jint predicate, jint code) {
536 return (jboolean)fdb_error_predicate(predicate, code);
537 }
538
Java_com_apple_foundationdb_FDB_Database_1create(JNIEnv * jenv,jobject,jstring clusterFileName)539 JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FDB_Database_1create(JNIEnv *jenv, jobject, jstring clusterFileName) {
540 const char* fileName = nullptr;
541 if(clusterFileName != JNI_NULL) {
542 fileName = jenv->GetStringUTFChars(clusterFileName, JNI_NULL);
543 if(jenv->ExceptionOccurred()) {
544 return 0;
545 }
546 }
547
548 FDBDatabase *db;
549 fdb_error_t err = fdb_create_database(fileName, &db);
550
551 if(clusterFileName != JNI_NULL) {
552 jenv->ReleaseStringUTFChars(clusterFileName, fileName);
553 }
554
555 if(err) {
556 safeThrow(jenv, getThrowable(jenv, err));
557 return 0;
558 }
559
560 return (jlong)db;
561 }
562
Java_com_apple_foundationdb_FDBTransaction_Transaction_1setVersion(JNIEnv * jenv,jobject,jlong tPtr,jlong version)563 JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1setVersion(JNIEnv *jenv, jobject, jlong tPtr, jlong version) {
564 if( !tPtr ) {
565 throwParamNotNull(jenv);
566 return;
567 }
568 FDBTransaction *tr = (FDBTransaction *)tPtr;
569 fdb_transaction_set_read_version( tr, version );
570 }
571
Java_com_apple_foundationdb_FDBTransaction_Transaction_1getReadVersion(JNIEnv * jenv,jobject,jlong tPtr)572 JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1getReadVersion(JNIEnv *jenv, jobject, jlong tPtr) {
573 if( !tPtr ) {
574 throwParamNotNull(jenv);
575 return 0;
576 }
577 FDBTransaction *tr = (FDBTransaction *)tPtr;
578 FDBFuture *f = fdb_transaction_get_read_version( tr );
579 return (jlong)f;
580 }
581
Java_com_apple_foundationdb_FDBTransaction_Transaction_1get(JNIEnv * jenv,jobject,jlong tPtr,jbyteArray keyBytes,jboolean snapshot)582 JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1get(JNIEnv *jenv, jobject, jlong tPtr, jbyteArray keyBytes, jboolean snapshot) {
583 if( !tPtr || !keyBytes ) {
584 throwParamNotNull(jenv);
585 return 0;
586 }
587 FDBTransaction *tr = (FDBTransaction *)tPtr;
588
589 uint8_t *barr = (uint8_t *)jenv->GetByteArrayElements( keyBytes, JNI_NULL );
590 if(!barr) {
591 if( !jenv->ExceptionOccurred() )
592 throwRuntimeEx( jenv, "Error getting handle to native resources" );
593 return 0;
594 }
595
596 FDBFuture *f = fdb_transaction_get( tr, barr, jenv->GetArrayLength( keyBytes ), (fdb_bool_t)snapshot );
597 jenv->ReleaseByteArrayElements( keyBytes, (jbyte *)barr, JNI_ABORT );
598 return (jlong)f;
599 }
600
Java_com_apple_foundationdb_FDBTransaction_Transaction_1getKey(JNIEnv * jenv,jobject,jlong tPtr,jbyteArray keyBytes,jboolean orEqual,jint offset,jboolean snapshot)601 JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1getKey(JNIEnv *jenv, jobject, jlong tPtr,
602 jbyteArray keyBytes, jboolean orEqual, jint offset, jboolean snapshot) {
603 if( !tPtr || !keyBytes ) {
604 throwParamNotNull(jenv);
605 return 0;
606 }
607 FDBTransaction *tr = (FDBTransaction *)tPtr;
608
609 uint8_t *barr = (uint8_t *)jenv->GetByteArrayElements( keyBytes, JNI_NULL );
610 if(!barr) {
611 if( !jenv->ExceptionOccurred() )
612 throwRuntimeEx( jenv, "Error getting handle to native resources" );
613 return 0;
614 }
615
616 FDBFuture *f = fdb_transaction_get_key( tr, barr, jenv->GetArrayLength( keyBytes ), orEqual, offset, (fdb_bool_t)snapshot );
617 jenv->ReleaseByteArrayElements( keyBytes, (jbyte *)barr, JNI_ABORT );
618 return (jlong)f;
619 }
620
Java_com_apple_foundationdb_FDBTransaction_Transaction_1getRange(JNIEnv * jenv,jobject,jlong tPtr,jbyteArray keyBeginBytes,jboolean orEqualBegin,jint offsetBegin,jbyteArray keyEndBytes,jboolean orEqualEnd,jint offsetEnd,jint rowLimit,jint targetBytes,jint streamingMode,jint iteration,jboolean snapshot,jboolean reverse)621 JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1getRange
622 (JNIEnv *jenv, jobject, jlong tPtr, jbyteArray keyBeginBytes, jboolean orEqualBegin, jint offsetBegin,
623 jbyteArray keyEndBytes, jboolean orEqualEnd, jint offsetEnd, jint rowLimit, jint targetBytes,
624 jint streamingMode, jint iteration, jboolean snapshot, jboolean reverse) {
625 if( !tPtr || !keyBeginBytes || !keyEndBytes ) {
626 throwParamNotNull(jenv);
627 return 0;
628 }
629 FDBTransaction *tr = (FDBTransaction *)tPtr;
630
631 uint8_t *barrBegin = (uint8_t *)jenv->GetByteArrayElements( keyBeginBytes, JNI_NULL );
632 if (!barrBegin) {
633 if( !jenv->ExceptionOccurred() )
634 throwRuntimeEx( jenv, "Error getting handle to native resources" );
635 return 0;
636 }
637
638 uint8_t *barrEnd = (uint8_t *)jenv->GetByteArrayElements( keyEndBytes, JNI_NULL );
639 if (!barrEnd) {
640 jenv->ReleaseByteArrayElements( keyBeginBytes, (jbyte *)barrBegin, JNI_ABORT );
641 if( !jenv->ExceptionOccurred() )
642 throwRuntimeEx( jenv, "Error getting handle to native resources" );
643 return 0;
644 }
645
646 FDBFuture *f = fdb_transaction_get_range( tr,
647 barrBegin, jenv->GetArrayLength( keyBeginBytes ), orEqualBegin, offsetBegin,
648 barrEnd, jenv->GetArrayLength( keyEndBytes ), orEqualEnd, offsetEnd, rowLimit,
649 targetBytes, (FDBStreamingMode)streamingMode, iteration, snapshot, reverse);
650 jenv->ReleaseByteArrayElements( keyBeginBytes, (jbyte *)barrBegin, JNI_ABORT );
651 jenv->ReleaseByteArrayElements( keyEndBytes, (jbyte *)barrEnd, JNI_ABORT );
652 return (jlong)f;
653 }
654
Java_com_apple_foundationdb_FDBTransaction_Transaction_1set(JNIEnv * jenv,jobject,jlong tPtr,jbyteArray keyBytes,jbyteArray valueBytes)655 JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1set(JNIEnv *jenv, jobject, jlong tPtr, jbyteArray keyBytes, jbyteArray valueBytes) {
656 if( !tPtr || !keyBytes || !valueBytes ) {
657 throwParamNotNull(jenv);
658 return;
659 }
660 FDBTransaction *tr = (FDBTransaction *)tPtr;
661
662 uint8_t *barrKey = (uint8_t *)jenv->GetByteArrayElements( keyBytes, JNI_NULL );
663 if (!barrKey) {
664 if( !jenv->ExceptionOccurred() )
665 throwRuntimeEx( jenv, "Error getting handle to native resources" );
666 return;
667 }
668
669 uint8_t *barrValue = (uint8_t *)jenv->GetByteArrayElements( valueBytes, JNI_NULL );
670 if (!barrValue) {
671 jenv->ReleaseByteArrayElements( keyBytes, (jbyte *)barrKey, JNI_ABORT );
672 if( !jenv->ExceptionOccurred() )
673 throwRuntimeEx( jenv, "Error getting handle to native resources" );
674 return;
675 }
676
677 fdb_transaction_set( tr,
678 barrKey, jenv->GetArrayLength( keyBytes ),
679 barrValue, jenv->GetArrayLength( valueBytes ) );
680 jenv->ReleaseByteArrayElements( keyBytes, (jbyte *)barrKey, JNI_ABORT );
681 jenv->ReleaseByteArrayElements( valueBytes, (jbyte *)barrValue, JNI_ABORT );
682 }
683
Java_com_apple_foundationdb_FDBTransaction_Transaction_1clear__J_3B(JNIEnv * jenv,jobject,jlong tPtr,jbyteArray keyBytes)684 JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1clear__J_3B(JNIEnv *jenv, jobject, jlong tPtr, jbyteArray keyBytes) {
685 if( !tPtr || !keyBytes ) {
686 throwParamNotNull(jenv);
687 return;
688 }
689 FDBTransaction *tr = (FDBTransaction *)tPtr;
690
691 uint8_t *barr = (uint8_t *)jenv->GetByteArrayElements( keyBytes, JNI_NULL );
692 if (!barr) {
693 if( !jenv->ExceptionOccurred() )
694 throwRuntimeEx( jenv, "Error getting handle to native resources" );
695 return;
696 }
697
698 fdb_transaction_clear( tr, barr, jenv->GetArrayLength( keyBytes ) );
699 jenv->ReleaseByteArrayElements( keyBytes, (jbyte *)barr, JNI_ABORT );
700 }
701
Java_com_apple_foundationdb_FDBTransaction_Transaction_1clear__J_3B_3B(JNIEnv * jenv,jobject,jlong tPtr,jbyteArray keyBeginBytes,jbyteArray keyEndBytes)702 JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1clear__J_3B_3B(JNIEnv *jenv, jobject, jlong tPtr, jbyteArray keyBeginBytes, jbyteArray keyEndBytes) {
703 if( !tPtr || !keyBeginBytes || !keyEndBytes ) {
704 throwParamNotNull(jenv);
705 return;
706 }
707 FDBTransaction *tr = (FDBTransaction *)tPtr;
708
709 uint8_t *barrKeyBegin = (uint8_t *)jenv->GetByteArrayElements( keyBeginBytes, JNI_NULL );
710 if (!barrKeyBegin) {
711 if( !jenv->ExceptionOccurred() )
712 throwRuntimeEx( jenv, "Error getting handle to native resources" );
713 return;
714 }
715
716 uint8_t *barrKeyEnd = (uint8_t *)jenv->GetByteArrayElements( keyEndBytes, JNI_NULL );
717 if (!barrKeyEnd) {
718 jenv->ReleaseByteArrayElements( keyBeginBytes, (jbyte *)barrKeyBegin, JNI_ABORT );
719 if( !jenv->ExceptionOccurred() )
720 throwRuntimeEx( jenv, "Error getting handle to native resources" );
721 return;
722 }
723
724 fdb_transaction_clear_range( tr,
725 barrKeyBegin, jenv->GetArrayLength( keyBeginBytes ),
726 barrKeyEnd, jenv->GetArrayLength( keyEndBytes ) );
727 jenv->ReleaseByteArrayElements( keyBeginBytes, (jbyte *)barrKeyBegin, JNI_ABORT );
728 jenv->ReleaseByteArrayElements( keyEndBytes, (jbyte *)barrKeyEnd, JNI_ABORT );
729 }
730
Java_com_apple_foundationdb_FDBTransaction_Transaction_1mutate(JNIEnv * jenv,jobject,jlong tPtr,jint code,jbyteArray key,jbyteArray value)731 JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1mutate(JNIEnv *jenv, jobject, jlong tPtr, jint code,
732 jbyteArray key, jbyteArray value ) {
733 if( !tPtr || !key || !value ) {
734 throwParamNotNull(jenv);
735 return;
736 }
737 FDBTransaction *tr = (FDBTransaction *)tPtr;
738
739 uint8_t *barrKey = (uint8_t *)jenv->GetByteArrayElements( key, JNI_NULL );
740 if (!barrKey) {
741 if( !jenv->ExceptionOccurred() )
742 throwRuntimeEx( jenv, "Error getting handle to native resources" );
743 return;
744 }
745
746 uint8_t *barrValue = (uint8_t *)jenv->GetByteArrayElements( value, JNI_NULL );
747 if (!barrValue) {
748 jenv->ReleaseByteArrayElements( key, (jbyte *)barrKey, JNI_ABORT );
749 if( !jenv->ExceptionOccurred() )
750 throwRuntimeEx( jenv, "Error getting handle to native resources" );
751 return;
752 }
753
754 fdb_transaction_atomic_op( tr,
755 barrKey, jenv->GetArrayLength( key ),
756 barrValue, jenv->GetArrayLength( value ),
757 (FDBMutationType)code);
758
759 jenv->ReleaseByteArrayElements( key, (jbyte *)barrKey, JNI_ABORT );
760 jenv->ReleaseByteArrayElements( value, (jbyte *)barrValue, JNI_ABORT );
761 }
762
Java_com_apple_foundationdb_FDBTransaction_Transaction_1commit(JNIEnv * jenv,jobject,jlong tPtr)763 JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1commit(JNIEnv *jenv, jobject, jlong tPtr) {
764 if( !tPtr ) {
765 throwParamNotNull(jenv);
766 return 0;
767 }
768 FDBTransaction *tr = (FDBTransaction *)tPtr;
769 FDBFuture *f = fdb_transaction_commit( tr );
770 return (jlong)f;
771 }
772
Java_com_apple_foundationdb_FDBTransaction_Transaction_1setOption(JNIEnv * jenv,jobject,jlong tPtr,jint code,jbyteArray value)773 JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1setOption(JNIEnv *jenv, jobject, jlong tPtr, jint code, jbyteArray value) {
774 if( !tPtr ) {
775 throwParamNotNull(jenv);
776 return;
777 }
778 FDBTransaction *tr = (FDBTransaction *)tPtr;
779 uint8_t *barr = nullptr;
780 int size = 0;
781
782 if(value != JNI_NULL) {
783 barr = (uint8_t *)jenv->GetByteArrayElements( value, JNI_NULL );
784 if (!barr) {
785 if( !jenv->ExceptionOccurred() )
786 throwRuntimeEx( jenv, "Error getting handle to native resources" );
787 return;
788 }
789 size = jenv->GetArrayLength( value );
790 }
791 fdb_error_t err = fdb_transaction_set_option( tr, (FDBTransactionOption)code, barr, size );
792 if(value != JNI_NULL)
793 jenv->ReleaseByteArrayElements( value, (jbyte *)barr, JNI_ABORT );
794 if( err ) {
795 safeThrow( jenv, getThrowable( jenv, err ) );
796 }
797 }
798
Java_com_apple_foundationdb_FDBTransaction_Transaction_1getCommittedVersion(JNIEnv * jenv,jobject,jlong tPtr)799 JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1getCommittedVersion(JNIEnv *jenv, jobject, jlong tPtr) {
800 if( !tPtr ) {
801 throwParamNotNull(jenv);
802 return 0;
803 }
804 FDBTransaction *tr = (FDBTransaction *)tPtr;
805 int64_t version;
806 fdb_error_t err = fdb_transaction_get_committed_version( tr, &version );
807 if( err ) {
808 safeThrow( jenv, getThrowable( jenv, err ) );
809 return 0;
810 }
811 return (jlong)version;
812 }
813
Java_com_apple_foundationdb_FDBTransaction_Transaction_1getVersionstamp(JNIEnv * jenv,jobject,jlong tPtr)814 JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1getVersionstamp(JNIEnv *jenv, jobject, jlong tPtr) {
815 if (!tPtr) {
816 throwParamNotNull(jenv);
817 return 0;
818 }
819 FDBTransaction *tr = (FDBTransaction *)tPtr;
820 FDBFuture *f = fdb_transaction_get_versionstamp(tr);
821 return (jlong)f;
822 }
823
Java_com_apple_foundationdb_FDBTransaction_Transaction_1getKeyLocations(JNIEnv * jenv,jobject,jlong tPtr,jbyteArray key)824 JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1getKeyLocations(JNIEnv *jenv, jobject, jlong tPtr, jbyteArray key) {
825 if( !tPtr || !key ) {
826 throwParamNotNull(jenv);
827 return 0;
828 }
829 FDBTransaction *tr = (FDBTransaction *)tPtr;
830
831 uint8_t *barr = (uint8_t *)jenv->GetByteArrayElements( key, JNI_NULL );
832 if (!barr) {
833 if( !jenv->ExceptionOccurred() )
834 throwRuntimeEx( jenv, "Error getting handle to native resources" );
835 return 0;
836 }
837 int size = jenv->GetArrayLength( key );
838
839 FDBFuture *f = fdb_transaction_get_addresses_for_key( tr, barr, size );
840
841 jenv->ReleaseByteArrayElements( key, (jbyte *)barr, JNI_ABORT );
842 return (jlong)f;
843 }
844
Java_com_apple_foundationdb_FDBTransaction_Transaction_1onError(JNIEnv * jenv,jobject,jlong tPtr,jint errorCode)845 JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1onError(JNIEnv *jenv, jobject, jlong tPtr, jint errorCode) {
846 if( !tPtr ) {
847 throwParamNotNull(jenv);
848 return 0;
849 }
850 FDBTransaction *tr = (FDBTransaction *)tPtr;
851 FDBFuture *f = fdb_transaction_on_error( tr, (fdb_error_t)errorCode );
852 return (jlong)f;
853 }
854
Java_com_apple_foundationdb_FDBTransaction_Transaction_1dispose(JNIEnv * jenv,jobject,jlong tPtr)855 JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1dispose(JNIEnv *jenv, jobject, jlong tPtr) {
856 if( !tPtr ) {
857 throwParamNotNull(jenv);
858 return;
859 }
860 fdb_transaction_destroy( (FDBTransaction *)tPtr );
861 }
862
Java_com_apple_foundationdb_FDBTransaction_Transaction_1reset(JNIEnv * jenv,jobject,jlong tPtr)863 JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1reset(JNIEnv *jenv, jobject, jlong tPtr) {
864 if( !tPtr ) {
865 throwParamNotNull(jenv);
866 return;
867 }
868 fdb_transaction_reset( (FDBTransaction *)tPtr );
869 }
870
Java_com_apple_foundationdb_FDBTransaction_Transaction_1watch(JNIEnv * jenv,jobject,jlong tPtr,jbyteArray key)871 JNIEXPORT jlong JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1watch(JNIEnv *jenv, jobject, jlong tPtr, jbyteArray key) {
872 if( !tPtr || !key ) {
873 throwParamNotNull(jenv);
874 return 0;
875 }
876 FDBTransaction *tr = (FDBTransaction *)tPtr;
877
878 uint8_t *barr = (uint8_t *)jenv->GetByteArrayElements( key, JNI_NULL );
879 if (!barr) {
880 if( !jenv->ExceptionOccurred() )
881 throwRuntimeEx( jenv, "Error getting handle to native resources" );
882 return 0;
883 }
884 int size = jenv->GetArrayLength( key );
885 FDBFuture *f = fdb_transaction_watch( tr, barr, size );
886
887 jenv->ReleaseByteArrayElements( key, (jbyte *)barr, JNI_ABORT );
888 return (jlong)f;
889 }
890
Java_com_apple_foundationdb_FDBTransaction_Transaction_1cancel(JNIEnv * jenv,jobject,jlong tPtr)891 JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1cancel(JNIEnv *jenv, jobject, jlong tPtr) {
892 if( !tPtr ) {
893 throwParamNotNull(jenv);
894 return;
895 }
896 fdb_transaction_cancel( (FDBTransaction *)tPtr );
897 }
898
Java_com_apple_foundationdb_FDBTransaction_Transaction_1addConflictRange(JNIEnv * jenv,jobject,jlong tPtr,jbyteArray keyBegin,jbyteArray keyEnd,jint conflictType)899 JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDBTransaction_Transaction_1addConflictRange(
900 JNIEnv *jenv, jobject, jlong tPtr, jbyteArray keyBegin, jbyteArray keyEnd, jint conflictType) {
901 if( !tPtr || !keyBegin || !keyEnd ) {
902 throwParamNotNull(jenv);
903 return;
904 }
905 FDBTransaction *tr = (FDBTransaction *)tPtr;
906
907 uint8_t *begin_barr = (uint8_t *)jenv->GetByteArrayElements( keyBegin, JNI_NULL );
908 if (!begin_barr) {
909 if( !jenv->ExceptionOccurred() )
910 throwRuntimeEx( jenv, "Error getting handle to native resources" );
911 return;
912 }
913 int begin_size = jenv->GetArrayLength( keyBegin );
914
915 uint8_t *end_barr = (uint8_t *)jenv->GetByteArrayElements( keyEnd, JNI_NULL );
916 if (!end_barr) {
917 jenv->ReleaseByteArrayElements( keyBegin, (jbyte *)begin_barr, JNI_ABORT );
918 if( !jenv->ExceptionOccurred() )
919 throwRuntimeEx( jenv, "Error getting handle to native resources" );
920 return;
921 }
922 int end_size = jenv->GetArrayLength( keyEnd );
923
924 fdb_error_t err = fdb_transaction_add_conflict_range( tr, begin_barr, begin_size, end_barr, end_size, (FDBConflictRangeType)conflictType );
925
926 jenv->ReleaseByteArrayElements( keyBegin, (jbyte *)begin_barr, JNI_ABORT );
927 jenv->ReleaseByteArrayElements( keyEnd, (jbyte *)end_barr, JNI_ABORT );
928
929 if( err ) {
930 safeThrow( jenv, getThrowable( jenv, err ) );
931 }
932 }
933
Java_com_apple_foundationdb_FDB_Select_1API_1version(JNIEnv * jenv,jclass,jint version)934 JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDB_Select_1API_1version(JNIEnv *jenv, jclass, jint version) {
935 fdb_error_t err = fdb_select_api_version( (int)version );
936 if( err ) {
937 if( err == 2203 ) {
938 int maxSupportedVersion = fdb_get_max_api_version();
939
940 char errorStr[1024];
941 if(FDB_API_VERSION > maxSupportedVersion) {
942 snprintf(errorStr, sizeof(errorStr), "This version of the FoundationDB Java binding is not supported by the installed "
943 "FoundationDB C library. The binding requires a library that supports API version "
944 "%d, but the installed library supports a maximum version of %d.",
945 FDB_API_VERSION, maxSupportedVersion);
946 }
947 else {
948 snprintf(errorStr, sizeof(errorStr), "API version %d is not supported by the installed FoundationDB C library.", version);
949 }
950
951 safeThrow( jenv, getThrowable( jenv, err, errorStr ) );
952 }
953 else {
954 safeThrow( jenv, getThrowable( jenv, err ) );
955 }
956 }
957 }
958
Java_com_apple_foundationdb_FDB_Network_1setOption(JNIEnv * jenv,jobject,jint code,jbyteArray value)959 JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDB_Network_1setOption(JNIEnv *jenv, jobject, jint code, jbyteArray value) {
960 uint8_t *barr = nullptr;
961 int size = 0;
962 if(value != JNI_NULL) {
963 barr = (uint8_t *)jenv->GetByteArrayElements( value, JNI_NULL );
964 if (!barr) {
965 if( !jenv->ExceptionOccurred() )
966 throwRuntimeEx( jenv, "Error getting handle to native resources" );
967 return;
968 }
969 size = jenv->GetArrayLength( value );
970 }
971 fdb_error_t err = fdb_network_set_option((FDBNetworkOption)code, barr, size);
972 if(value != JNI_NULL)
973 jenv->ReleaseByteArrayElements( value, (jbyte *)barr, JNI_ABORT );
974 if( err ) {
975 safeThrow( jenv, getThrowable( jenv, err ) );
976 }
977 }
978
Java_com_apple_foundationdb_FDB_Network_1setup(JNIEnv * jenv,jobject)979 JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDB_Network_1setup(JNIEnv *jenv, jobject) {
980 fdb_error_t err = fdb_setup_network();
981 if( err ) {
982 safeThrow( jenv, getThrowable( jenv, err ) );
983 }
984 }
985
Java_com_apple_foundationdb_FDB_Network_1run(JNIEnv * jenv,jobject)986 JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDB_Network_1run(JNIEnv *jenv, jobject) {
987 // initialize things for the callbacks on the network thread
988 g_thread_jenv = jenv;
989 if( !g_IFutureCallback_call_methodID ) {
990 if( !findCallbackMethods( jenv ) )
991 return;
992 }
993
994 fdb_error_t hookErr = fdb_add_network_thread_completion_hook( &detachIfExternalThread, nullptr );
995 if( hookErr ) {
996 safeThrow( jenv, getThrowable( jenv, hookErr ) );
997 }
998
999 fdb_error_t err = fdb_run_network();
1000 if( err ) {
1001 safeThrow( jenv, getThrowable( jenv, err ) );
1002 }
1003 }
1004
Java_com_apple_foundationdb_FDB_Network_1stop(JNIEnv * jenv,jobject)1005 JNIEXPORT void JNICALL Java_com_apple_foundationdb_FDB_Network_1stop(JNIEnv *jenv, jobject) {
1006 fdb_error_t err = fdb_stop_network();
1007 if( err ) {
1008 safeThrow( jenv, getThrowable( jenv, err ) );
1009 }
1010 }
1011
JNI_OnLoad(JavaVM * vm,void * reserved)1012 jint JNI_OnLoad(JavaVM *vm, void *reserved) {
1013 g_jvm = vm;
1014 return JNI_VERSION_1_1;
1015 }
1016
1017 #ifdef __cplusplus
1018 }
1019 #endif
1020
1021