git.delta.rocks / jrsonnet / refs/commits / 3c2d9ee98ad3

difftreelog

feat thread_enter/thread_exit bindins

Yaroslav Bolyukin2024-06-18parent: #9070b9a.patch.diff
in: master

5 files changed

modifiedCargo.tomldiffbeforeafterboth
20jrsonnet-cli = { path = "./crates/jrsonnet-cli", version = "0.5.0-pre96" }20jrsonnet-cli = { path = "./crates/jrsonnet-cli", version = "0.5.0-pre96" }
21jrsonnet-types = { path = "./crates/jrsonnet-types", version = "0.5.0-pre96" }21jrsonnet-types = { path = "./crates/jrsonnet-types", version = "0.5.0-pre96" }
22
23jrsonnet-gcmodule = "0.3.6"22jrsonnet-gcmodule = { version = "0.3.7" }
24
25# Diagnostics.23# Diagnostics.
26# hi-doc is my library, which handles text formatting very well, but isn't polished enough yet24# hi-doc is my library, which handles text formatting very well, but isn't polished enough yet
modifiedbindings/c/libjsonnet.hdiffbeforeafterboth
1/*
2Copyright 2015 Google Inc. All rights reserved.
3Licensed under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License.
5You may obtain a copy of the License at
6 http://www.apache.org/licenses/LICENSE-2.0
7Unless required by applicable law or agreed to in writing, software
8distributed under the License is distributed on an "AS IS" BASIS,
9WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10See the License for the specific language governing permissions and
11limitations under the License.
12*/
13
14#ifndef LIB_JSONNET_H1#ifndef LIB_JSONNET_H
15#define LIB_JSONNET_H2#define LIB_JSONNET_H
163
17#include <stddef.h>4#include <stddef.h>
185
19/** \file This file is a library interface for evaluating Jsonnet. It is written in C++ but exposes6/** \file This file is a library interface for evaluating Jsonnet. It is written in Rust but exposes
20 * a C interface for easier wrapping by other languages. See \see jsonnet_lib_test.c for an example7 * a C interface for easier wrapping by other languages. See \see jsonnet_lib_test.c for an example
21 * of using the library.8 * of using the library.
22 */9 */
2310
24/** The version string of th Jsonnet interpreter.11/** The version string of th Jsonnet interpreter.
25 *12 *
28 *15 *
29 * If this isn't the sae as jsonnet_version() then you've got a mismatched binary / header.16 * If this isn't the sae as jsonnet_version() then you've got a mismatched binary / header.
30 */17 */
31#define LIB_JSONNET_VERSION "v0.16.0"18#define LIB_JSONNET_VERSION "v0.20.0"
3219
33/** Return the version string of the Jsonnet interpreter. Conforms to semantic versioning20/** Return the version string of the Jsonnet interpreter. Conforms to semantic versioning
34 * http://semver.org/ If this does not match LIB_JSONNET_VERSION then there is a mismatch between21 * https://semver.org/ If this does not match LIB_JSONNET_VERSION then there is a mismatch between
35 * header and compiled library.22 * header and compiled library.
36 */23 */
37const char *jsonnet_version(void);24const char *jsonnet_version(void);
3825
39/** Jsonnet virtual machine context. */26/** Jsonnet virtual machine context. */
54/** Expect a string as output and don't JSON encode it. */41/** Expect a string as output and don't JSON encode it. */
55void jsonnet_string_output(struct JsonnetVm *vm, int v);42void jsonnet_string_output(struct JsonnetVm *vm, int v);
5643
57/** Callback used to load imports.44/** Callback used to load imports.
58 *45 *
59 * The returned char* should be allocated with jsonnet_realloc. It will be cleaned up by46 * The returned char* should be allocated with jsonnet_realloc. It will be cleaned up by
60 * libjsonnet when no-longer needed.47 * libjsonnet when no-longer needed.
61 *48 *
62 * \param ctx User pointer, given in jsonnet_import_callback.49 * \param ctx User pointer, given in jsonnet_import_callback.
63 * \param base The directory containing the code that did the import.50 * \param base The directory containing the code that did the import.
64 * \param rel The path imported by the code.51 * \param rel The path imported by the code.
65 * \param found_here Set this byref param to path to the file, absolute or relative to the52 * \param found_here Set this byref param to path to the file, absolute or relative to the
66 * process's CWD. This is necessary so that imports from the content of the imported file can53 * process's CWD. This is necessary so that imports from the content of the imported file can
67 * be resolved correctly. Allocate memory with jsonnet_realloc. Only use when *success = 1.54 * be resolved correctly. Allocate memory with jsonnet_realloc. Only use when *success = 1.
68 * \param success Set this byref param to 1 to indicate success and 0 for failure.55 * \param success Set this byref param to 1 to indicate success and 0 for failure.
69 * \returns The content of the imported file, or an error message.56 * \param buf Set this byref param to the content of the imported file, or an error message. Allocate memory with jsonnet_realloc. Do not include a null terminator byte.
57 * \param buflen Set this byref param to the length of the data returned in buf.
58 * \returns 0 to indicate success and 1 for failure. On success, the content is in *buf. On failure, an error message is in *buf.
70 */59 */
71typedef char *JsonnetImportCallback(void *ctx, const char *base, const char *rel, char **found_here,60typedef int JsonnetImportCallback(void *ctx, const char *base, const char *rel,
72 int *success);61 char **found_here, char **buf, size_t *buflen);
7362
74/** An opaque type which can only be utilized via the jsonnet_json_* family of functions.63/** An opaque type which can only be utilized via the jsonnet_json_* family of functions.
75 */64 */
289/** Complement of \see jsonnet_vm_make. */278/** Complement of \see jsonnet_vm_make. */
290void jsonnet_destroy(struct JsonnetVm *vm);279void jsonnet_destroy(struct JsonnetVm *vm);
280
281/** Jrsonnet addition.
282 *
283 * In jrsonnet, vm state is bound to the thread, because interpreter
284 * also uses thread_local storage for some things (I.e GC).
285 *
286 * It makes it impossible to correctly use those bindings in golang,
287 * where developer has little control over goroutine scheduler.
288 *
289 * To make it work, jrsonnet provides methods to dump and restore thread
290 * state manually, making it possible to wire it with golang.
291 */
292struct JrThreadCTX;
293
294/** Dump current thread state, to be restored with
295 * jrsonnet_reenter_thread.
296 */
297struct JrThreadCTX *jrsonnet_exit_thread();
298/** Restore thread state, freeing JrThreadCTX.
299 */
300void jrsonnet_reenter_thread(struct JrThreadCTX *ctx);
301
302struct JrThreadId;
303
304/** Get current thread id (opaque pointer).
305 */
306struct JrThreadId* jrsonnet_thread_id();
307
308/** Compare two thread ids, it is not the same as a == b.
309 *
310 * \returns 1 if the same thread, 0 otherwise
311 */
312int jrsonnet_thread_id_compare(struct JrThreadId *a, struct JrThreadId *b);
313
314/** Free thread id value.
315 */
316void jrsonnet_thread_id_free(struct JrThreadId *id);
291317
292#endif // LIB_JSONNET_H318#endif // LIB_JSONNET_H
293319
modifiedbindings/jsonnet/Cargo.tomldiffbeforeafterboth
23jrsonnet-parser.workspace = true23jrsonnet-parser.workspace = true
24jrsonnet-stdlib.workspace = true24jrsonnet-stdlib.workspace = true
25jrsonnet-gcmodule.workspace = true25jrsonnet-gcmodule.workspace = true
26jrsonnet-interner.workspace = true
2627
27[lib]28[lib]
28name = "jsonnet"29name = "jsonnet"
modifiedbindings/jsonnet/src/lib.rsdiffbeforeafterboth
40/// then there is a mismatch between header and compiled library.40/// then there is a mismatch between header and compiled library.
41#[no_mangle]41#[no_mangle]
42pub extern "C" fn jsonnet_version() -> &'static [u8; 8] {42pub extern "C" fn jsonnet_version() -> &'static [u8; 8] {
43 b"v0.19.1\0"43 b"v0.20.0\0"
44}44}
4545
46unsafe fn parse_path(input: &CStr) -> Cow<Path> {46unsafe fn parse_path(input: &CStr) -> Cow<Path> {
modifiedcrates/jrsonnet-interner/src/lib.rsdiffbeforeafterboth
219 }219 }
220}220}
221
222type PoolMap = HashMap<Inner, (), BuildHasherDefault<FxHasher>>;
221223
222thread_local! {224thread_local! {
223 static POOL: RefCell<HashMap<Inner, (), BuildHasherDefault<FxHasher>>> = RefCell::new(HashMap::with_capacity_and_hasher(200, BuildHasherDefault::default()));225 static POOL: RefCell<PoolMap> = RefCell::new(HashMap::with_capacity_and_hasher(200, BuildHasherDefault::default()));
224}226}
227
228/// Jrsonnet golang bindings require that it is possible to move jsonnet
229/// VM between OS threads, and this is not possible due to usage of
230/// `thread_local`. Instead, there is two methods added, one should be
231/// called at the end of current thread work, and one that should be
232/// used when using other thread.
233pub mod interop {
234 use std::mem;
235
236 use crate::{PoolMap, POOL};
237
238 pub enum PoolState {}
239
240 /// Dump current interned string pool, to be restored by
241 /// `reenter_thread`
242 pub fn exit_thread() -> *mut PoolState {
243 Box::into_raw(Box::new(POOL.with_borrow_mut(mem::take))).cast()
244 }
245
246 /// Reenter thread, using state dumped by `exit_thread`.
247 ///
248 /// # Safety
249 ///
250 /// `state` should be acquired from `exit_thread`, it is not allowed
251 /// to reuse state to reenter multiple threads.
252 pub unsafe fn reenter_thread(state: *mut PoolState) {
253 let ptr: *mut PoolMap = state.cast();
254 // SAFETY: ptr is an unique state per method safety requirements.
255 let ptr: Box<PoolMap> = unsafe { Box::from_raw(ptr) };
256 let ptr: PoolMap = *ptr;
257 POOL.with_borrow_mut(|pool| {
258 let _ = mem::replace(pool, ptr);
259 });
260 }
261}
225262
226#[must_use]263#[must_use]
227pub fn intern_bytes(bytes: &[u8]) -> IBytes {264pub fn intern_bytes(bytes: &[u8]) -> IBytes {