|
1 | 1 | #ifndef NIM_FFI_LIB_ECHO_H_INCLUDED |
2 | 2 | #define NIM_FFI_LIB_ECHO_H_INCLUDED |
3 | 3 | #include "nim_ffi_cbor.h" |
| 4 | +#include "nim_ffi_sync.h" |
4 | 5 |
|
5 | 6 | /* ============================================================ */ |
6 | 7 | /* Generated types (user-declared + per-proc request envelopes) */ |
@@ -287,6 +288,67 @@ static inline int echo_ctx_create(const EchoConfig* config, EchoCreateFn on_crea |
287 | 288 | return 0; |
288 | 289 | } |
289 | 290 |
|
| 291 | +static inline int echo_ctx_create_sync(const EchoConfig* config, EchoCtx** out, char* err_buf, size_t err_len, uint32_t timeout_ms) { |
| 292 | + EchoCreateCtorReq ffi_req; |
| 293 | + memset(&ffi_req, 0, sizeof(ffi_req)); |
| 294 | + ffi_req.config = *config; |
| 295 | + uint8_t* req_buf = NULL; |
| 296 | + size_t req_len = 0; |
| 297 | + char* enc_err = NULL; |
| 298 | + if (nimffi_encode_to_buf(echo_encv_EchoCreateCtorReq, &ffi_req, &req_buf, &req_len, &enc_err) != 0) { |
| 299 | + nimffi_copy_err(err_buf, err_len, enc_err ? enc_err : "encode failed"); |
| 300 | + free(enc_err); |
| 301 | + return -1; |
| 302 | + } |
| 303 | + NimFfiSyncState* st = nimffi_sync_state_new(); |
| 304 | + if (!st) { |
| 305 | + free(req_buf); |
| 306 | + nimffi_copy_err(err_buf, err_len, "out of memory"); |
| 307 | + return -1; |
| 308 | + } |
| 309 | + (void)echo_create(req_buf, req_len, nimffi_sync_cb, st); |
| 310 | + free(req_buf); |
| 311 | + if (!nimffi_sync_wait(st, timeout_ms)) { |
| 312 | + nimffi_copy_err(err_buf, err_len, "FFI create timed out"); |
| 313 | + nimffi_sync_state_release(st); |
| 314 | + return -1; |
| 315 | + } |
| 316 | + if (!st->ok) { |
| 317 | + nimffi_copy_err(err_buf, err_len, st->err ? st->err : "FFI create failed"); |
| 318 | + int rc = st->ret_code ? st->ret_code : -1; |
| 319 | + nimffi_sync_state_release(st); |
| 320 | + return rc; |
| 321 | + } |
| 322 | + NimFfiStr addr; |
| 323 | + memset(&addr, 0, sizeof(addr)); |
| 324 | + char* dec_err = NULL; |
| 325 | + if (nimffi_decode_from_buf(echo_decv_Str, st->bytes, st->bytes_len, &addr, &dec_err) != 0) { |
| 326 | + nimffi_copy_err(err_buf, err_len, dec_err ? dec_err : "decode failed"); |
| 327 | + free(dec_err); |
| 328 | + nimffi_sync_state_release(st); |
| 329 | + return -1; |
| 330 | + } |
| 331 | + char* endp = NULL; |
| 332 | + unsigned long long a = addr.data ? strtoull(addr.data, &endp, 10) : 0; |
| 333 | + bool ok = addr.data && addr.len > 0 && endp && *endp == '\0'; |
| 334 | + nimffi_free_str(&addr); |
| 335 | + if (!ok) { |
| 336 | + nimffi_copy_err(err_buf, err_len, "FFI create returned non-numeric address"); |
| 337 | + nimffi_sync_state_release(st); |
| 338 | + return -1; |
| 339 | + } |
| 340 | + EchoCtx* c = (EchoCtx*)calloc(1, sizeof(EchoCtx)); |
| 341 | + if (!c) { |
| 342 | + nimffi_copy_err(err_buf, err_len, "out of memory"); |
| 343 | + nimffi_sync_state_release(st); |
| 344 | + return -1; |
| 345 | + } |
| 346 | + c->ptr = (void*)(uintptr_t)a; |
| 347 | + *out = c; |
| 348 | + nimffi_sync_state_release(st); |
| 349 | + return 0; |
| 350 | +} |
| 351 | + |
290 | 352 | static inline void echo_ctx_destroy(EchoCtx* ctx) { |
291 | 353 | if (!ctx) return; |
292 | 354 | if (ctx->ptr) { echo_destroy(ctx->ptr); ctx->ptr = NULL; } |
@@ -353,6 +415,57 @@ static inline int echo_ctx_shout(const EchoCtx* ctx, const ShoutRequest* req, Ec |
353 | 415 | return 0; |
354 | 416 | } |
355 | 417 |
|
| 418 | +static inline int echo_ctx_shout_sync(const EchoCtx* ctx, const ShoutRequest* req, ShoutResponse* out, char* err_buf, size_t err_len, uint32_t timeout_ms) { |
| 419 | + EchoShoutReq ffi_req; |
| 420 | + memset(&ffi_req, 0, sizeof(ffi_req)); |
| 421 | + ffi_req.req = *req; |
| 422 | + uint8_t* req_buf = NULL; |
| 423 | + size_t req_len = 0; |
| 424 | + char* enc_err = NULL; |
| 425 | + if (nimffi_encode_to_buf(echo_encv_EchoShoutReq, &ffi_req, &req_buf, &req_len, &enc_err) != 0) { |
| 426 | + nimffi_copy_err(err_buf, err_len, enc_err ? enc_err : "encode failed"); |
| 427 | + free(enc_err); |
| 428 | + return -1; |
| 429 | + } |
| 430 | + NimFfiSyncState* st = nimffi_sync_state_new(); |
| 431 | + if (!st) { |
| 432 | + free(req_buf); |
| 433 | + nimffi_copy_err(err_buf, err_len, "out of memory"); |
| 434 | + return -1; |
| 435 | + } |
| 436 | + int ret = echo_shout(ctx->ptr, nimffi_sync_cb, st, req_buf, req_len); |
| 437 | + free(req_buf); |
| 438 | + if (ret == NIMFFI_RET_MISSING_CALLBACK) { |
| 439 | + nimffi_copy_err(err_buf, err_len, "RET_MISSING_CALLBACK (internal error)"); |
| 440 | + nimffi_sync_state_release(st); |
| 441 | + nimffi_sync_state_release(st); |
| 442 | + return -1; |
| 443 | + } |
| 444 | + if (!nimffi_sync_wait(st, timeout_ms)) { |
| 445 | + nimffi_copy_err(err_buf, err_len, "FFI call timed out"); |
| 446 | + nimffi_sync_state_release(st); |
| 447 | + return -1; |
| 448 | + } |
| 449 | + if (!st->ok) { |
| 450 | + nimffi_copy_err(err_buf, err_len, st->err ? st->err : "FFI call failed"); |
| 451 | + int rc = st->ret_code ? st->ret_code : -1; |
| 452 | + nimffi_sync_state_release(st); |
| 453 | + return rc; |
| 454 | + } |
| 455 | + memset(out, 0, sizeof(*out)); |
| 456 | + char* dec_err = NULL; |
| 457 | + int dec = nimffi_decode_from_buf(echo_decv_ShoutResponse, st->bytes, st->bytes_len, out, &dec_err); |
| 458 | + if (dec != 0) { |
| 459 | + nimffi_copy_err(err_buf, err_len, dec_err ? dec_err : "decode failed"); |
| 460 | + free(dec_err); |
| 461 | + echo_free_ShoutResponse(out); |
| 462 | + nimffi_sync_state_release(st); |
| 463 | + return -1; |
| 464 | + } |
| 465 | + nimffi_sync_state_release(st); |
| 466 | + return 0; |
| 467 | +} |
| 468 | + |
356 | 469 | typedef void (*EchoVersionReplyFn)(int err_code, const NimFfiStr* reply, const char* err_msg, void* user_data); |
357 | 470 | typedef struct { EchoVersionReplyFn fn; void* user_data; } EchoVersionCallBox; |
358 | 471 | static void echo_version_reply_trampoline(int ret, const char* msg, size_t len, void* ud) { |
@@ -412,4 +525,54 @@ static inline int echo_ctx_version(const EchoCtx* ctx, EchoVersionReplyFn on_rep |
412 | 525 | return 0; |
413 | 526 | } |
414 | 527 |
|
| 528 | +static inline int echo_ctx_version_sync(const EchoCtx* ctx, NimFfiStr* out, char* err_buf, size_t err_len, uint32_t timeout_ms) { |
| 529 | + EchoVersionReq ffi_req; |
| 530 | + memset(&ffi_req, 0, sizeof(ffi_req)); |
| 531 | + uint8_t* req_buf = NULL; |
| 532 | + size_t req_len = 0; |
| 533 | + char* enc_err = NULL; |
| 534 | + if (nimffi_encode_to_buf(echo_encv_EchoVersionReq, &ffi_req, &req_buf, &req_len, &enc_err) != 0) { |
| 535 | + nimffi_copy_err(err_buf, err_len, enc_err ? enc_err : "encode failed"); |
| 536 | + free(enc_err); |
| 537 | + return -1; |
| 538 | + } |
| 539 | + NimFfiSyncState* st = nimffi_sync_state_new(); |
| 540 | + if (!st) { |
| 541 | + free(req_buf); |
| 542 | + nimffi_copy_err(err_buf, err_len, "out of memory"); |
| 543 | + return -1; |
| 544 | + } |
| 545 | + int ret = echo_version(ctx->ptr, nimffi_sync_cb, st, req_buf, req_len); |
| 546 | + free(req_buf); |
| 547 | + if (ret == NIMFFI_RET_MISSING_CALLBACK) { |
| 548 | + nimffi_copy_err(err_buf, err_len, "RET_MISSING_CALLBACK (internal error)"); |
| 549 | + nimffi_sync_state_release(st); |
| 550 | + nimffi_sync_state_release(st); |
| 551 | + return -1; |
| 552 | + } |
| 553 | + if (!nimffi_sync_wait(st, timeout_ms)) { |
| 554 | + nimffi_copy_err(err_buf, err_len, "FFI call timed out"); |
| 555 | + nimffi_sync_state_release(st); |
| 556 | + return -1; |
| 557 | + } |
| 558 | + if (!st->ok) { |
| 559 | + nimffi_copy_err(err_buf, err_len, st->err ? st->err : "FFI call failed"); |
| 560 | + int rc = st->ret_code ? st->ret_code : -1; |
| 561 | + nimffi_sync_state_release(st); |
| 562 | + return rc; |
| 563 | + } |
| 564 | + memset(out, 0, sizeof(*out)); |
| 565 | + char* dec_err = NULL; |
| 566 | + int dec = nimffi_decode_from_buf(echo_decv_Str, st->bytes, st->bytes_len, out, &dec_err); |
| 567 | + if (dec != 0) { |
| 568 | + nimffi_copy_err(err_buf, err_len, dec_err ? dec_err : "decode failed"); |
| 569 | + free(dec_err); |
| 570 | + nimffi_free_str(out); |
| 571 | + nimffi_sync_state_release(st); |
| 572 | + return -1; |
| 573 | + } |
| 574 | + nimffi_sync_state_release(st); |
| 575 | + return 0; |
| 576 | +} |
| 577 | + |
415 | 578 | #endif /* NIM_FFI_LIB_ECHO_H_INCLUDED */ |
0 commit comments